Updated on 2026-08-14
This commit is contained in:
parent
17b31dd192
commit
8fb493fef6
27 changed files with 322 additions and 157 deletions
|
|
@ -79,10 +79,9 @@ dependencies {
|
||||||
implementation 'com.google.android.play:core-ktx:1.8.1'
|
implementation 'com.google.android.play:core-ktx:1.8.1'
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||||
|
|
||||||
// implementation 'com.tangem:blockchain:develop-67'
|
implementation 'com.tangem:blockchain:develop-70'
|
||||||
implementation 'com.tangem:blockchain:0.0.1'
|
implementation 'com.tangem.tangem-sdk-kotlin:core:develop-142'
|
||||||
implementation 'com.tangem.tangem-sdk-kotlin:core:0.0.1'
|
implementation 'com.tangem.tangem-sdk-kotlin:android:develop-142'
|
||||||
implementation 'com.tangem.tangem-sdk-kotlin:android:0.0.1'
|
|
||||||
|
|
||||||
// WebView
|
// WebView
|
||||||
implementation "androidx.browser:browser:1.3.0"
|
implementation "androidx.browser:browser:1.3.0"
|
||||||
|
|
|
||||||
|
|
@ -4,36 +4,16 @@ import androidx.annotation.DrawableRes
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.wallet.R
|
import com.tangem.wallet.R
|
||||||
|
|
||||||
@DrawableRes
|
|
||||||
fun Blockchain.getIconRes(): Int {
|
|
||||||
return when (this) {
|
|
||||||
Blockchain.Unknown -> R.drawable.shape_circle
|
|
||||||
Blockchain.Ducatus -> R.drawable.ic_ducatus
|
|
||||||
Blockchain.Bitcoin, Blockchain.BitcoinTestnet,-> R.drawable.ic_btc
|
|
||||||
Blockchain.BitcoinCash -> R.drawable.ic_btc_cash
|
|
||||||
Blockchain.Litecoin -> R.drawable.ic_ltc
|
|
||||||
Blockchain.Ethereum, Blockchain.EthereumTestnet, -> R.drawable.ic_eth
|
|
||||||
Blockchain.RSK -> R.drawable.ic_rsk
|
|
||||||
Blockchain.Cardano, Blockchain.CardanoShelley -> R.drawable.ic_cardano
|
|
||||||
Blockchain.Binance, Blockchain.BinanceTestnet -> R.drawable.ic_binance
|
|
||||||
Blockchain.Tezos -> R.drawable.ic_tezos
|
|
||||||
Blockchain.XRP -> R.drawable.ic_xrp
|
|
||||||
Blockchain.Stellar -> R.drawable.ic_stellar
|
|
||||||
else -> R.drawable.shape_circle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
fun Blockchain.getRoundIconRes(): Int {
|
fun Blockchain.getRoundIconRes(): Int {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
// Blockchain.Ducatus -> R.drawable.ic_ducatus
|
Blockchain.Ducatus -> R.drawable.ic_ducatus
|
||||||
Blockchain.Bitcoin, Blockchain.BitcoinTestnet,-> R.drawable.ic_bitcoin_round
|
Blockchain.Bitcoin, Blockchain.BitcoinTestnet,-> R.drawable.ic_bitcoin_round
|
||||||
Blockchain.BitcoinCash -> R.drawable.ic_bitcoin_cash_round
|
Blockchain.BitcoinCash -> R.drawable.ic_bitcoin_cash_round
|
||||||
Blockchain.Litecoin -> R.drawable.ic_litecoin_round
|
Blockchain.Litecoin -> R.drawable.ic_litecoin_round
|
||||||
Blockchain.Ethereum, Blockchain.EthereumTestnet, -> R.drawable.ic_eth_round
|
Blockchain.Ethereum, Blockchain.EthereumTestnet, -> R.drawable.ic_eth_round
|
||||||
Blockchain.RSK -> R.drawable.ic_rsk_round
|
Blockchain.RSK -> R.drawable.ic_rsk_round
|
||||||
Blockchain.Cardano, Blockchain.CardanoShelley -> R.drawable.ic_cardano_round
|
Blockchain.Cardano, Blockchain.CardanoShelley -> R.drawable.ic_cardano_round
|
||||||
Blockchain.Binance, Blockchain.BinanceTestnet -> R.drawable.ic_binance_round
|
|
||||||
Blockchain.Tezos -> R.drawable.ic_tezos_round
|
Blockchain.Tezos -> R.drawable.ic_tezos_round
|
||||||
Blockchain.XRP -> R.drawable.ic_xrp_round
|
Blockchain.XRP -> R.drawable.ic_xrp_round
|
||||||
Blockchain.Stellar -> R.drawable.ic_stellar_round
|
Blockchain.Stellar -> R.drawable.ic_stellar_round
|
||||||
|
|
@ -41,7 +21,7 @@ fun Blockchain.getRoundIconRes(): Int {
|
||||||
Blockchain.Polygon, Blockchain.PolygonTestnet -> R.drawable.ic_polygon_round
|
Blockchain.Polygon, Blockchain.PolygonTestnet -> R.drawable.ic_polygon_round
|
||||||
Blockchain.Solana, Blockchain.SolanaTestnet -> R.drawable.ic_solana_round
|
Blockchain.Solana, Blockchain.SolanaTestnet -> R.drawable.ic_solana_round
|
||||||
Blockchain.Fantom, Blockchain.FantomTestnet -> R.drawable.ic_fantom_round
|
Blockchain.Fantom, Blockchain.FantomTestnet -> R.drawable.ic_fantom_round
|
||||||
Blockchain.BSC, Blockchain.BSCTestnet -> R.drawable.ic_bsc_round
|
Blockchain.BSC, Blockchain.BSCTestnet, Blockchain.Binance, Blockchain.BinanceTestnet -> R.drawable.ic_bsc_round
|
||||||
else -> R.drawable.ic_tangem_logo
|
else -> R.drawable.ic_tangem_logo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -56,7 +36,6 @@ fun Blockchain.getGreyedOutIconRes(): Int {
|
||||||
Blockchain.Ethereum, Blockchain.EthereumTestnet, -> R.drawable.ic_eth_no_color
|
Blockchain.Ethereum, Blockchain.EthereumTestnet, -> R.drawable.ic_eth_no_color
|
||||||
Blockchain.RSK -> R.drawable.ic_rsk_no_color
|
Blockchain.RSK -> R.drawable.ic_rsk_no_color
|
||||||
Blockchain.Cardano, Blockchain.CardanoShelley -> R.drawable.ic_cardano_no_color
|
Blockchain.Cardano, Blockchain.CardanoShelley -> R.drawable.ic_cardano_no_color
|
||||||
Blockchain.Binance, Blockchain.BinanceTestnet -> R.drawable.ic_binance_no_color
|
|
||||||
Blockchain.Tezos -> R.drawable.ic_tezos_no_color
|
Blockchain.Tezos -> R.drawable.ic_tezos_no_color
|
||||||
Blockchain.XRP -> R.drawable.ic_xrp_no_color
|
Blockchain.XRP -> R.drawable.ic_xrp_no_color
|
||||||
Blockchain.Stellar -> R.drawable.ic_stellar_no_color
|
Blockchain.Stellar -> R.drawable.ic_stellar_no_color
|
||||||
|
|
@ -64,7 +43,7 @@ fun Blockchain.getGreyedOutIconRes(): Int {
|
||||||
Blockchain.Polygon, Blockchain.PolygonTestnet -> R.drawable.ic_polygon_no_color
|
Blockchain.Polygon, Blockchain.PolygonTestnet -> R.drawable.ic_polygon_no_color
|
||||||
Blockchain.Solana, Blockchain.SolanaTestnet -> R.drawable.ic_solana_no_color
|
Blockchain.Solana, Blockchain.SolanaTestnet -> R.drawable.ic_solana_no_color
|
||||||
Blockchain.Fantom, Blockchain.FantomTestnet -> R.drawable.ic_fantom_no_color
|
Blockchain.Fantom, Blockchain.FantomTestnet -> R.drawable.ic_fantom_no_color
|
||||||
Blockchain.BSC, Blockchain.BSCTestnet -> R.drawable.ic_bsc_no_color
|
Blockchain.BSC, Blockchain.BSCTestnet, Blockchain.Binance, Blockchain.BinanceTestnet -> R.drawable.ic_bsc_no_color
|
||||||
else -> R.drawable.ic_tangem_logo
|
else -> R.drawable.ic_tangem_logo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.tangem.tap.common.extensions
|
package com.tangem.tap.common.extensions
|
||||||
|
|
||||||
import android.graphics.*
|
import android.graphics.*
|
||||||
import android.net.Uri
|
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.constraintlayout.utils.widget.ImageFilterView
|
import androidx.constraintlayout.utils.widget.ImageFilterView
|
||||||
import com.squareup.picasso.Callback
|
import com.squareup.picasso.Callback
|
||||||
|
|
@ -11,6 +10,8 @@ import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.blockchain.common.IconsUtil
|
import com.tangem.blockchain.common.IconsUtil
|
||||||
import com.tangem.blockchain.common.Token
|
import com.tangem.blockchain.common.Token
|
||||||
import com.tangem.tap.domain.extensions.getCustomIconUrl
|
import com.tangem.tap.domain.extensions.getCustomIconUrl
|
||||||
|
import com.tangem.tap.domain.tokens.getIconUrl
|
||||||
|
import com.tangem.tap.domain.tokens.toNetworkId
|
||||||
import com.tangem.wallet.R
|
import com.tangem.wallet.R
|
||||||
|
|
||||||
fun Picasso.loadCurrenciesIcon(
|
fun Picasso.loadCurrenciesIcon(
|
||||||
|
|
@ -20,10 +21,11 @@ fun Picasso.loadCurrenciesIcon(
|
||||||
blockchain: Blockchain,
|
blockchain: Blockchain,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val url = if (token != null) {
|
val url: String? = if (token != null) {
|
||||||
token.getCustomIconUrl()?.let { Uri.parse(it) } ?: IconsUtil.getTokenIconUri(blockchain, token)
|
token.id?.let { getIconUrl(it) } ?: token.getCustomIconUrl()
|
||||||
|
?: IconsUtil.getTokenIconUri(blockchain, token)?.toString()
|
||||||
} else {
|
} else {
|
||||||
IconsUtil.getBlockchainIconUri(blockchain)
|
getIconUrl(blockchain.toNetworkId())
|
||||||
}
|
}
|
||||||
|
|
||||||
imageView.setImageDrawable(null)
|
imageView.setImageDrawable(null)
|
||||||
|
|
@ -85,7 +87,7 @@ private fun setBlockchainImage(
|
||||||
textView: TextView,
|
textView: TextView,
|
||||||
blockchain: Blockchain,
|
blockchain: Blockchain,
|
||||||
) {
|
) {
|
||||||
imageView.setImageResource(blockchain.getIconRes())
|
imageView.setImageResource(blockchain.getRoundIconRes())
|
||||||
imageView.colorFilter = null
|
imageView.colorFilter = null
|
||||||
if (blockchain.isTestnet()) imageView.saturation = 0f
|
if (blockchain.isTestnet()) imageView.saturation = 0f
|
||||||
textView.text = null
|
textView.text = null
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import com.tangem.tap.common.extensions.withMainContext
|
||||||
import com.tangem.tap.common.redux.global.FiatCurrencyName
|
import com.tangem.tap.common.redux.global.FiatCurrencyName
|
||||||
import com.tangem.tap.common.redux.global.GlobalAction
|
import com.tangem.tap.common.redux.global.GlobalAction
|
||||||
import com.tangem.tap.currenciesRepository
|
import com.tangem.tap.currenciesRepository
|
||||||
|
import com.tangem.tap.domain.TapWorkarounds.derivationStyle
|
||||||
import com.tangem.tap.domain.TapWorkarounds.isStart2Coin
|
import com.tangem.tap.domain.TapWorkarounds.isStart2Coin
|
||||||
import com.tangem.tap.domain.TapWorkarounds.isTestCard
|
import com.tangem.tap.domain.TapWorkarounds.isTestCard
|
||||||
import com.tangem.tap.domain.configurable.config.ConfigManager
|
import com.tangem.tap.domain.configurable.config.ConfigManager
|
||||||
|
|
@ -190,7 +191,7 @@ class TapWalletManager {
|
||||||
primaryWalletManager: WalletManager?
|
primaryWalletManager: WalletManager?
|
||||||
) {
|
) {
|
||||||
val primaryTokens = primaryWalletManager?.cardTokens?.toList() ?: emptyList()
|
val primaryTokens = primaryWalletManager?.cardTokens?.toList() ?: emptyList()
|
||||||
val savedCurrencies = currenciesRepository.loadSavedCurrencies(scanResponse.card.cardId)
|
val savedCurrencies = currenciesRepository.loadSavedCurrencies(scanResponse.card.cardId, scanResponse.card.derivationStyle)
|
||||||
|
|
||||||
if (savedCurrencies.isEmpty()) {
|
if (savedCurrencies.isEmpty()) {
|
||||||
if (primaryBlockchain != null && primaryWalletManager != null) {
|
if (primaryBlockchain != null && primaryWalletManager != null) {
|
||||||
|
|
@ -205,9 +206,10 @@ class TapWalletManager {
|
||||||
)
|
)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
val derivationStyle = scanResponse.card.derivationStyle
|
||||||
val blockchainNetworks = listOf(
|
val blockchainNetworks = listOf(
|
||||||
BlockchainNetwork(Blockchain.Bitcoin,null, emptyList()),
|
BlockchainNetwork(Blockchain.Bitcoin, scanResponse.card),
|
||||||
BlockchainNetwork(Blockchain.Ethereum,null, emptyList())
|
BlockchainNetwork(Blockchain.Ethereum, scanResponse.card)
|
||||||
)
|
)
|
||||||
|
|
||||||
val walletManagers = walletManagerFactory.makeWalletManagersForApp(
|
val walletManagers = walletManagerFactory.makeWalletManagersForApp(
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import com.tangem.operations.issuerAndUserData.ReadIssuerDataCommand
|
||||||
import com.tangem.tap.domain.ProductType
|
import com.tangem.tap.domain.ProductType
|
||||||
import com.tangem.tap.domain.TapSdkError
|
import com.tangem.tap.domain.TapSdkError
|
||||||
import com.tangem.tap.domain.TapWorkarounds
|
import com.tangem.tap.domain.TapWorkarounds
|
||||||
|
import com.tangem.tap.domain.TapWorkarounds.derivationStyle
|
||||||
import com.tangem.tap.domain.TapWorkarounds.getTangemNoteBlockchain
|
import com.tangem.tap.domain.TapWorkarounds.getTangemNoteBlockchain
|
||||||
import com.tangem.tap.domain.TapWorkarounds.isExcluded
|
import com.tangem.tap.domain.TapWorkarounds.isExcluded
|
||||||
import com.tangem.tap.domain.TapWorkarounds.isNotSupportedInThatRelease
|
import com.tangem.tap.domain.TapWorkarounds.isNotSupportedInThatRelease
|
||||||
|
|
@ -275,7 +276,7 @@ private class ScanWalletProcessor(
|
||||||
|
|
||||||
private fun getBlockchainsToDerive(card: Card): List<BlockchainNetwork> {
|
private fun getBlockchainsToDerive(card: Card): List<BlockchainNetwork> {
|
||||||
val currenciesRepository = currenciesRepository ?: return emptyList()
|
val currenciesRepository = currenciesRepository ?: return emptyList()
|
||||||
val cardCurrencies = currenciesRepository.loadSavedCurrencies(card.cardId).toMutableList()
|
val cardCurrencies = currenciesRepository.loadSavedCurrencies(card.cardId, card.derivationStyle).toMutableList()
|
||||||
|
|
||||||
val blockchainsToDerive = cardCurrencies.ifEmpty {
|
val blockchainsToDerive = cardCurrencies.ifEmpty {
|
||||||
mutableListOf(
|
mutableListOf(
|
||||||
|
|
|
||||||
|
|
@ -98,13 +98,19 @@ class CurrenciesRepository(val context: Application) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadSavedCurrencies(cardId: String): List<BlockchainNetwork> {
|
fun loadSavedCurrencies(
|
||||||
|
cardId: String,
|
||||||
|
derivationStyle: DerivationStyle? = null
|
||||||
|
): List<BlockchainNetwork> {
|
||||||
if (DemoHelper.isDemoCardId(cardId)) {
|
if (DemoHelper.isDemoCardId(cardId)) {
|
||||||
return loadDemoCurrencies(cardId)
|
return loadDemoCurrencies(cardId)
|
||||||
}
|
}
|
||||||
return try {
|
return try {
|
||||||
val json = context.readFileText(getFileNameForBlockchains(cardId))
|
val json = context.readFileText(getFileNameForBlockchains(cardId))
|
||||||
blockchainNetworkAdapter.fromJson(json)?.distinct() ?: loadSavedCurrenciesOldWay(cardId)
|
blockchainNetworkAdapter.fromJson(json)?.distinct() ?: loadSavedCurrenciesOldWay(
|
||||||
|
cardId,
|
||||||
|
derivationStyle
|
||||||
|
)
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
|
|
@ -120,16 +126,25 @@ class CurrenciesRepository(val context: Application) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadSavedCurrenciesOldWay(cardId: String): List<BlockchainNetwork> {
|
private fun loadSavedCurrenciesOldWay(
|
||||||
|
cardId: String, derivationStyle: DerivationStyle?
|
||||||
|
): List<BlockchainNetwork> {
|
||||||
val blockchains = loadSavedBlockchains(cardId)
|
val blockchains = loadSavedBlockchains(cardId)
|
||||||
val tokens = loadSavedTokens(cardId)
|
val tokens = loadSavedTokens(cardId)
|
||||||
|
val currencies = getSupportedTokens()
|
||||||
val blockchainNetworks = blockchains.map { blockchain ->
|
val blockchainNetworks = blockchains.map { blockchain ->
|
||||||
BlockchainNetwork(
|
BlockchainNetwork(
|
||||||
blockchain = blockchain,
|
blockchain = blockchain,
|
||||||
derivationPath = null,
|
derivationPath = blockchain.derivationPath(derivationStyle)?.rawPath,
|
||||||
tokens = tokens
|
tokens = tokens
|
||||||
.filter { it.blockchainDao.toBlockchain() == blockchain }
|
.filter { it.blockchainDao.toBlockchain() == blockchain }
|
||||||
.map { it.toToken() }
|
.map {
|
||||||
|
val token = it.toToken()
|
||||||
|
val id = currencies
|
||||||
|
.find { it.contracts?.find { it.address == token.contractAddress } != null }
|
||||||
|
?.id
|
||||||
|
token.copy(id = id)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
saveCurrencies(cardId, blockchainNetworks) // migrate saved currencies
|
saveCurrencies(cardId, blockchainNetworks) // migrate saved currencies
|
||||||
|
|
@ -178,17 +193,6 @@ class CurrenciesRepository(val context: Application) {
|
||||||
return obsoleteTokensAdapter.fromJson(tokenJson)!!.map { it.toTokenDao(blockchain) }
|
return obsoleteTokensAdapter.fromJson(tokenJson)!!.map { it.toTokenDao(blockchain) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSupportedTokens(): List<Blockchain> {
|
|
||||||
return listOf(
|
|
||||||
Blockchain.Ethereum,
|
|
||||||
Blockchain.BSC,
|
|
||||||
Blockchain.Binance,
|
|
||||||
Blockchain.Polygon,
|
|
||||||
Blockchain.Avalanche,
|
|
||||||
Blockchain.Fantom,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getBlockchains(
|
fun getBlockchains(
|
||||||
cardFirmware: FirmwareVersion,
|
cardFirmware: FirmwareVersion,
|
||||||
isTestNet: Boolean = false
|
isTestNet: Boolean = false
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ data class CurrenciesFromJson(
|
||||||
|
|
||||||
|
|
||||||
fun List<ContractFromJson>.toContracts(): List<Contract> {
|
fun List<ContractFromJson>.toContracts(): List<Contract> {
|
||||||
return map { Contract.fromJsonObject(it) }
|
return mapNotNull { Contract.fromJsonObject(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Currency(
|
data class Currency(
|
||||||
|
|
@ -59,10 +59,11 @@ data class Contract(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromJsonObject(contract: ContractFromJson): Contract {
|
fun fromJsonObject(contract: ContractFromJson): Contract? {
|
||||||
|
val blockchain = Blockchain.fromNetworkId(contract.networkId) ?: return null
|
||||||
return Contract(
|
return Contract(
|
||||||
networkId = contract.networkId,
|
networkId = contract.networkId,
|
||||||
blockchain = Blockchain.fromNetworkId(contract.networkId),
|
blockchain = blockchain,
|
||||||
address = contract.address,
|
address = contract.address,
|
||||||
decimalCount = contract.decimalCount,
|
decimalCount = contract.decimalCount,
|
||||||
iconUrl = getIconUrl(contract.networkId)
|
iconUrl = getIconUrl(contract.networkId)
|
||||||
|
|
@ -76,7 +77,7 @@ fun getIconUrl(id: String): String {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain {
|
fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? {
|
||||||
return when (networkId) {
|
return when (networkId) {
|
||||||
"avalanche" -> Blockchain.Avalanche
|
"avalanche" -> Blockchain.Avalanche
|
||||||
"binancecoin" -> Blockchain.Binance
|
"binancecoin" -> Blockchain.Binance
|
||||||
|
|
@ -95,7 +96,7 @@ fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain {
|
||||||
"stellar" -> Blockchain.Stellar
|
"stellar" -> Blockchain.Stellar
|
||||||
"tezos" -> Blockchain.Tezos
|
"tezos" -> Blockchain.Tezos
|
||||||
"ripple" -> Blockchain.XRP
|
"ripple" -> Blockchain.XRP
|
||||||
else -> Blockchain.Unknown
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,7 +104,7 @@ fun Blockchain.toNetworkId(): String {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
Blockchain.Unknown -> "unknown"
|
Blockchain.Unknown -> "unknown"
|
||||||
Blockchain.Avalanche -> "avalanche"
|
Blockchain.Avalanche -> "avalanche"
|
||||||
Blockchain.AvalancheTestnet -> "avalaunch"
|
Blockchain.AvalancheTestnet -> "avalaunche"
|
||||||
Blockchain.Binance -> "binancecoin"
|
Blockchain.Binance -> "binancecoin"
|
||||||
Blockchain.BinanceTestnet -> "binancecoin"
|
Blockchain.BinanceTestnet -> "binancecoin"
|
||||||
Blockchain.BSC -> "binance-smart-chain"
|
Blockchain.BSC -> "binance-smart-chain"
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ class WalletConnectMiddleware {
|
||||||
blockchainToMake,
|
blockchainToMake,
|
||||||
card.derivationStyle?.let { DerivationParams.Default(it) }
|
card.derivationStyle?.let { DerivationParams.Default(it) }
|
||||||
)
|
)
|
||||||
if (currenciesRepository.loadSavedCurrencies(card.cardId)
|
if (currenciesRepository.loadSavedCurrencies(card.cardId, card.derivationStyle)
|
||||||
.find { it.blockchain == blockchainToMake } != null
|
.find { it.blockchain == blockchainToMake } != null
|
||||||
) {
|
) {
|
||||||
walletManager?.let {
|
walletManager?.let {
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ class AdditionalEmailInfo {
|
||||||
var address: String = "",
|
var address: String = "",
|
||||||
var explorerLink: String = "",
|
var explorerLink: String = "",
|
||||||
var host: String = "",
|
var host: String = "",
|
||||||
|
var derivationPath: String = "",
|
||||||
)
|
)
|
||||||
|
|
||||||
var appVersion: String = ""
|
var appVersion: String = ""
|
||||||
|
|
@ -159,7 +160,8 @@ class AdditionalEmailInfo {
|
||||||
blockchain = manager.wallet.blockchain,
|
blockchain = manager.wallet.blockchain,
|
||||||
address = getAddress(manager.wallet),
|
address = getAddress(manager.wallet),
|
||||||
explorerLink = getExploreUri(manager.wallet),
|
explorerLink = getExploreUri(manager.wallet),
|
||||||
host = manager.currentHost
|
host = manager.currentHost,
|
||||||
|
derivationPath = manager.wallet.publicKey.derivationPath?.rawPath ?: ""
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if (manager.cardTokens.isNotEmpty()) {
|
if (manager.cardTokens.isNotEmpty()) {
|
||||||
|
|
@ -173,7 +175,8 @@ class AdditionalEmailInfo {
|
||||||
blockchain = wallet.blockchain,
|
blockchain = wallet.blockchain,
|
||||||
address = getAddress(wallet),
|
address = getAddress(wallet),
|
||||||
explorerLink = getExploreUri(wallet),
|
explorerLink = getExploreUri(wallet),
|
||||||
host = host
|
host = host,
|
||||||
|
derivationPath = wallet.publicKey.derivationPath?.rawPath ?: ""
|
||||||
)
|
)
|
||||||
|
|
||||||
this.destinationAddress = destinationAddress
|
this.destinationAddress = destinationAddress
|
||||||
|
|
@ -325,6 +328,7 @@ class EmailDataBuilder(
|
||||||
builder.appendKeyValue("Blockchain", it.blockchain.fullName)
|
builder.appendKeyValue("Blockchain", it.blockchain.fullName)
|
||||||
builder.appendKeyValue("Host", it.host)
|
builder.appendKeyValue("Host", it.host)
|
||||||
builder.appendKeyValue("Wallet address", it.address)
|
builder.appendKeyValue("Wallet address", it.address)
|
||||||
|
builder.appendKeyValue("Derivation path", it.derivationPath)
|
||||||
builder.appendKeyValue("Explorer link", it.explorerLink)
|
builder.appendKeyValue("Explorer link", it.explorerLink)
|
||||||
|
|
||||||
infoHolder.tokens[it.blockchain]?.let { tokens ->
|
infoHolder.tokens[it.blockchain]?.let { tokens ->
|
||||||
|
|
@ -332,6 +336,7 @@ class EmailDataBuilder(
|
||||||
appendLine()
|
appendLine()
|
||||||
tokens.forEach { token ->
|
tokens.forEach { token ->
|
||||||
builder.appendKeyValue("Name", token.name)
|
builder.appendKeyValue("Name", token.name)
|
||||||
|
if (token.id != null) builder.appendKeyValue("Id", token.id ?: "")
|
||||||
builder.appendKeyValue("Contract address", token.contractAddress)
|
builder.appendKeyValue("Contract address", token.contractAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -342,6 +347,7 @@ class EmailDataBuilder(
|
||||||
fun appendTxFailedBlockchainInfo(error: String): EmailDataBuilder {
|
fun appendTxFailedBlockchainInfo(error: String): EmailDataBuilder {
|
||||||
val walletInfo = infoHolder.onSendErrorWalletInfo ?: AdditionalEmailInfo.EmailWalletInfo()
|
val walletInfo = infoHolder.onSendErrorWalletInfo ?: AdditionalEmailInfo.EmailWalletInfo()
|
||||||
builder.appendKeyValue("Blockchain", walletInfo.blockchain.fullName)
|
builder.appendKeyValue("Blockchain", walletInfo.blockchain.fullName)
|
||||||
|
builder.appendKeyValue("Derivation path", walletInfo.derivationPath)
|
||||||
builder.appendKeyValue("Host", walletInfo.host)
|
builder.appendKeyValue("Host", walletInfo.host)
|
||||||
builder.appendKeyValue("Token", infoHolder.token)
|
builder.appendKeyValue("Token", infoHolder.token)
|
||||||
builder.appendKeyValue("Error", error)
|
builder.appendKeyValue("Error", error)
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,13 @@ import androidx.fragment.app.Fragment
|
||||||
import androidx.transition.TransitionInflater
|
import androidx.transition.TransitionInflater
|
||||||
import by.kirich1409.viewbindingdelegate.viewBinding
|
import by.kirich1409.viewbindingdelegate.viewBinding
|
||||||
import com.google.accompanist.appcompattheme.AppCompatTheme
|
import com.google.accompanist.appcompattheme.AppCompatTheme
|
||||||
|
import com.tangem.blockchain.common.Blockchain
|
||||||
|
import com.tangem.tap.common.extensions.copyToClipboard
|
||||||
|
import com.tangem.tap.common.extensions.dispatchNotification
|
||||||
import com.tangem.tap.common.extensions.getString
|
import com.tangem.tap.common.extensions.getString
|
||||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||||
|
import com.tangem.tap.features.tokens.redux.ContractAddress
|
||||||
|
import com.tangem.tap.features.tokens.redux.TokenWithBlockchain
|
||||||
import com.tangem.tap.features.tokens.redux.TokensAction
|
import com.tangem.tap.features.tokens.redux.TokensAction
|
||||||
import com.tangem.tap.features.tokens.redux.TokensState
|
import com.tangem.tap.features.tokens.redux.TokensState
|
||||||
import com.tangem.tap.features.tokens.ui.compose.CurrenciesScreen
|
import com.tangem.tap.features.tokens.ui.compose.CurrenciesScreen
|
||||||
|
|
@ -68,14 +73,22 @@ class AddTokensFragment : Fragment(R.layout.fragment_add_tokens),
|
||||||
(activity as? AppCompatActivity)?.setSupportActionBar(toolbar)
|
(activity as? AppCompatActivity)?.setSupportActionBar(toolbar)
|
||||||
toolbar.setNavigationOnClickListener { activity?.onBackPressed() }
|
toolbar.setNavigationOnClickListener { activity?.onBackPressed() }
|
||||||
|
|
||||||
|
val onSaveChanges = { tokens: List<TokenWithBlockchain>, blockchains: List<Blockchain> ->
|
||||||
|
store.dispatch(TokensAction.SaveChanges(tokens, blockchains))
|
||||||
|
}
|
||||||
|
val onNetworkItemClicked = { contractAddress: ContractAddress ->
|
||||||
|
context?.copyToClipboard(contractAddress)
|
||||||
|
store.dispatchNotification(R.string.contract_address_copied_message)
|
||||||
|
}
|
||||||
|
|
||||||
cvCurrencies.setContent {
|
cvCurrencies.setContent {
|
||||||
AppCompatTheme {
|
AppCompatTheme {
|
||||||
CurrenciesScreen(
|
CurrenciesScreen(
|
||||||
tokensState = tokensState,
|
tokensState = tokensState,
|
||||||
searchInput = searchInput
|
searchInput = searchInput,
|
||||||
) { tokens, blockchains ->
|
onSaveChanges = onSaveChanges,
|
||||||
store.dispatch(TokensAction.SaveChanges(tokens, blockchains))
|
onNetworkItemClicked = onNetworkItemClicked
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,7 @@ fun CollapsedCurrencyItem(
|
||||||
.clickable(onClick = { onCurrencyClick(currency.id) })
|
.clickable(onClick = { onCurrencyClick(currency.id) })
|
||||||
) {
|
) {
|
||||||
val blockchain = Blockchain.fromNetworkId(currency.id)
|
val blockchain = Blockchain.fromNetworkId(currency.id)
|
||||||
val iconRes = if (blockchain == Blockchain.Unknown) {
|
val iconRes = currency.iconUrl
|
||||||
currency.iconUrl
|
|
||||||
} else {
|
|
||||||
blockchain.getRoundIconRes()
|
|
||||||
}
|
|
||||||
|
|
||||||
SubcomposeAsyncImage(
|
SubcomposeAsyncImage(
|
||||||
model = iconRes,
|
model = iconRes,
|
||||||
|
|
@ -66,32 +62,36 @@ fun CollapsedCurrencyItem(
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.size(6.dp))
|
Spacer(modifier = Modifier.size(6.dp))
|
||||||
Row {
|
Row {
|
||||||
if (currency.contracts != null) {
|
if (!currency.contracts.isNullOrEmpty()) {
|
||||||
currency.contracts.map { contract ->
|
currency.contracts.map { contract ->
|
||||||
val added =
|
if (contract.address == currency.symbol) {
|
||||||
addedTokens.map { it.token.contractAddress }.contains(contract.address)
|
BlockchainNetworkItem(
|
||||||
val icon = if (added) {
|
blockchain = Blockchain.fromNetworkId(contract.networkId),
|
||||||
contract.blockchain.getRoundIconRes()
|
addedBlockchains = addedBlockchains
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
contract.blockchain.getGreyedOutIconRes()
|
val added =
|
||||||
|
addedTokens.map { it.token.contractAddress }
|
||||||
|
.contains(contract.address)
|
||||||
|
val icon = if (added) {
|
||||||
|
contract.blockchain.getRoundIconRes()
|
||||||
|
} else {
|
||||||
|
contract.blockchain.getGreyedOutIconRes()
|
||||||
|
}
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = icon),
|
||||||
|
contentDescription = null,
|
||||||
|
Modifier
|
||||||
|
.size(20.dp)
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.size(5.dp))
|
||||||
}
|
}
|
||||||
Image(
|
|
||||||
painter = painterResource(id = icon),
|
|
||||||
contentDescription = null,
|
|
||||||
Modifier
|
|
||||||
.size(20.dp)
|
|
||||||
)
|
|
||||||
Spacer(modifier = Modifier.size(5.dp))
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val added = addedBlockchains.contains(blockchain)
|
BlockchainNetworkItem(
|
||||||
val icon =
|
blockchain = blockchain,
|
||||||
if (added) blockchain.getRoundIconRes() else blockchain.getGreyedOutIconRes()
|
addedBlockchains = addedBlockchains
|
||||||
Image(
|
|
||||||
painter = painterResource(id = icon),
|
|
||||||
contentDescription = null,
|
|
||||||
Modifier
|
|
||||||
.size(20.dp)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -105,4 +105,23 @@ fun CollapsedCurrencyItem(
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BlockchainNetworkItem(
|
||||||
|
blockchain: Blockchain?,
|
||||||
|
addedBlockchains: List<Blockchain>
|
||||||
|
) {
|
||||||
|
val added = addedBlockchains.contains(blockchain)
|
||||||
|
val icon =
|
||||||
|
if (added) blockchain?.getRoundIconRes() else blockchain?.getGreyedOutIconRes()
|
||||||
|
if (icon != null) {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = icon),
|
||||||
|
contentDescription = null,
|
||||||
|
Modifier
|
||||||
|
.size(20.dp)
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.size(5.dp))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.tangem.tap.features.tokens.ui.compose
|
package com.tangem.tap.features.tokens.ui.compose
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.ExtendedFloatingActionButton
|
import androidx.compose.material.ExtendedFloatingActionButton
|
||||||
import androidx.compose.material.FabPosition
|
import androidx.compose.material.FabPosition
|
||||||
|
|
@ -17,6 +18,7 @@ import com.tangem.tap.common.compose.keyboardAsState
|
||||||
import com.tangem.tap.common.extensions.pixelsToDp
|
import com.tangem.tap.common.extensions.pixelsToDp
|
||||||
import com.tangem.tap.domain.tokens.Currency
|
import com.tangem.tap.domain.tokens.Currency
|
||||||
import com.tangem.tap.domain.tokens.fromNetworkId
|
import com.tangem.tap.domain.tokens.fromNetworkId
|
||||||
|
import com.tangem.tap.features.tokens.redux.ContractAddress
|
||||||
import com.tangem.tap.features.tokens.redux.TokenWithBlockchain
|
import com.tangem.tap.features.tokens.redux.TokenWithBlockchain
|
||||||
import com.tangem.tap.features.tokens.redux.TokensState
|
import com.tangem.tap.features.tokens.redux.TokensState
|
||||||
import com.tangem.tap.store
|
import com.tangem.tap.store
|
||||||
|
|
@ -26,7 +28,8 @@ import com.tangem.wallet.R
|
||||||
fun CurrenciesScreen(
|
fun CurrenciesScreen(
|
||||||
tokensState: MutableState<TokensState> = mutableStateOf(store.state.tokensState),
|
tokensState: MutableState<TokensState> = mutableStateOf(store.state.tokensState),
|
||||||
searchInput: MutableState<String>,
|
searchInput: MutableState<String>,
|
||||||
onSaveChanges: (List<TokenWithBlockchain>, List<Blockchain>) -> Unit
|
onSaveChanges: (List<TokenWithBlockchain>, List<Blockchain>) -> Unit,
|
||||||
|
onNetworkItemClicked: (ContractAddress) -> Unit
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val addedTokensState = remember { mutableStateOf(tokensState.value.addedTokens) }
|
val addedTokensState = remember { mutableStateOf(tokensState.value.addedTokens) }
|
||||||
|
|
@ -49,7 +52,7 @@ fun CurrenciesScreen(
|
||||||
if (mutableList.contains(blockchain)) {
|
if (mutableList.contains(blockchain)) {
|
||||||
mutableList.remove(blockchain)
|
mutableList.remove(blockchain)
|
||||||
} else {
|
} else {
|
||||||
mutableList.add(blockchain)
|
blockchain?.let { mutableList.add(blockchain) }
|
||||||
}
|
}
|
||||||
addedBlockchainsState.value = mutableList
|
addedBlockchainsState.value = mutableList
|
||||||
}
|
}
|
||||||
|
|
@ -65,16 +68,21 @@ fun CurrenciesScreen(
|
||||||
floatingActionButtonPosition = FabPosition.Center,
|
floatingActionButtonPosition = FabPosition.Center,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
ListOfCurrencies(
|
Column {
|
||||||
currencies = tokensState.value.currencies,
|
if (tokensState.value.allowToAdd) CurrenciesWarning()
|
||||||
nonRemovableTokens = tokensState.value.nonRemovableTokens,
|
ListOfCurrencies(
|
||||||
nonRemovableBlockchains = tokensState.value.nonRemovableBlockchains,
|
currencies = tokensState.value.currencies,
|
||||||
addedTokens = addedTokensState.value,
|
nonRemovableTokens = tokensState.value.nonRemovableTokens,
|
||||||
addedBlockchains = addedBlockchainsState.value,
|
nonRemovableBlockchains = tokensState.value.nonRemovableBlockchains,
|
||||||
searchInput = searchInput.value,
|
addedTokens = addedTokensState.value,
|
||||||
allowToAdd = tokensState.value.allowToAdd,
|
addedBlockchains = addedBlockchainsState.value,
|
||||||
onAddCurrencyToggled = onAddCurrencyToggleClick
|
searchInput = searchInput.value,
|
||||||
)
|
allowToAdd = tokensState.value.allowToAdd,
|
||||||
|
onAddCurrencyToggled = onAddCurrencyToggleClick,
|
||||||
|
onNetworkItemClicked = onNetworkItemClicked
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.tangem.tap.features.tokens.ui.compose
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
|
import androidx.compose.ui.text.SpanStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.tangem.wallet.R
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CurrenciesWarning() {
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(16.dp)
|
||||||
|
.background(Color(0xFFF2F2F2), shape = RoundedCornerShape(10.dp))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
val warning = stringResource(id = R.string.alert_manage_tokens_addresses_message)
|
||||||
|
val end = warning.indexOf(" ")
|
||||||
|
val spanStyles = listOf(
|
||||||
|
AnnotatedString.Range(
|
||||||
|
SpanStyle(fontWeight = FontWeight.Bold),
|
||||||
|
start = 0,
|
||||||
|
end = end
|
||||||
|
)
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = AnnotatedString(text = warning, spanStyles = spanStyles),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
color = Color(0xFF848488),
|
||||||
|
modifier = Modifier.padding(
|
||||||
|
top = 8.dp,
|
||||||
|
bottom = 8.dp,
|
||||||
|
start = 16.dp,
|
||||||
|
end = 16.dp
|
||||||
|
),
|
||||||
|
fontSize = 13.sp,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,7 +16,8 @@ fun CurrencyItem(
|
||||||
allowToAdd: Boolean,
|
allowToAdd: Boolean,
|
||||||
expanded: Boolean,
|
expanded: Boolean,
|
||||||
onCurrencyClick: (String) -> Unit,
|
onCurrencyClick: (String) -> Unit,
|
||||||
onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit
|
onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit,
|
||||||
|
onNetworkItemClicked: (ContractAddress) -> Unit
|
||||||
) {
|
) {
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
ExpandedCurrencyItem(
|
ExpandedCurrencyItem(
|
||||||
|
|
@ -26,7 +27,8 @@ fun CurrencyItem(
|
||||||
addedTokens = addedTokens,
|
addedTokens = addedTokens,
|
||||||
addedBlockchains = addedBlockchains,
|
addedBlockchains = addedBlockchains,
|
||||||
allowToAdd = allowToAdd,
|
allowToAdd = allowToAdd,
|
||||||
onCurrencyClick = onCurrencyClick, onAddCurrencyToggled = onAddCurrencyToggled
|
onCurrencyClick = onCurrencyClick, onAddCurrencyToggled = onAddCurrencyToggled,
|
||||||
|
onNetworkItemClicked = onNetworkItemClicked
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
CollapsedCurrencyItem(
|
CollapsedCurrencyItem(
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import coil.compose.SubcomposeAsyncImage
|
import coil.compose.SubcomposeAsyncImage
|
||||||
import com.tangem.blockchain.common.Blockchain
|
import com.tangem.blockchain.common.Blockchain
|
||||||
import com.tangem.tap.common.extensions.getRoundIconRes
|
|
||||||
import com.tangem.tap.domain.tokens.Currency
|
import com.tangem.tap.domain.tokens.Currency
|
||||||
import com.tangem.tap.domain.tokens.fromNetworkId
|
import com.tangem.tap.domain.tokens.fromNetworkId
|
||||||
import com.tangem.tap.features.tokens.redux.ContractAddress
|
import com.tangem.tap.features.tokens.redux.ContractAddress
|
||||||
|
|
@ -34,14 +33,11 @@ fun ExpandedCurrencyItem(
|
||||||
addedBlockchains: List<Blockchain>,
|
addedBlockchains: List<Blockchain>,
|
||||||
allowToAdd: Boolean,
|
allowToAdd: Boolean,
|
||||||
onCurrencyClick: (String) -> Unit,
|
onCurrencyClick: (String) -> Unit,
|
||||||
onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit
|
onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit,
|
||||||
|
onNetworkItemClicked: (ContractAddress) -> Unit
|
||||||
) {
|
) {
|
||||||
val blockchain = Blockchain.fromNetworkId(currency.id)
|
val blockchain = Blockchain.fromNetworkId(currency.id)
|
||||||
val iconRes = if (blockchain == Blockchain.Unknown) {
|
val iconRes = currency.iconUrl
|
||||||
currency.iconUrl
|
|
||||||
} else {
|
|
||||||
blockchain.getRoundIconRes()
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
Row(
|
Row(
|
||||||
|
|
@ -89,7 +85,7 @@ fun ExpandedCurrencyItem(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val blockchains = currency.contracts?.map { it.blockchain } ?: listOf(
|
val blockchains = currency.contracts?.map { it.blockchain } ?: listOfNotNull(
|
||||||
Blockchain.fromNetworkId(currency.id)
|
Blockchain.fromNetworkId(currency.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -99,11 +95,18 @@ fun ExpandedCurrencyItem(
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
) {
|
) {
|
||||||
if (blockchains.size > 1) {
|
if (blockchains.size > 1) {
|
||||||
|
val dividerHeight = if (blockchains.size == 2) {
|
||||||
|
60
|
||||||
|
} else if (blockchains.size == 3) {
|
||||||
|
110
|
||||||
|
} else {
|
||||||
|
43 * blockchains.size
|
||||||
|
}
|
||||||
Divider(
|
Divider(
|
||||||
color = Color(0xFFDEDEDE),
|
color = Color(0xFFDEDEDE),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.height((43 * blockchains.size - 1).dp)
|
.height(dividerHeight.dp)
|
||||||
.padding(start = 37.dp, top = 16.dp)
|
.padding(start = 37.5.dp)
|
||||||
.width(1.dp)
|
.width(1.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -130,12 +133,12 @@ fun ExpandedCurrencyItem(
|
||||||
) {
|
) {
|
||||||
blockchains.map { blockchain ->
|
blockchains.map { blockchain ->
|
||||||
val contract = currency.contracts?.firstOrNull { it.blockchain == blockchain }
|
val contract = currency.contracts?.firstOrNull { it.blockchain == blockchain }
|
||||||
val added = if (contract != null) {
|
val added = if (contract != null && contract.address != currency.symbol) {
|
||||||
addedTokens.map { it.token.contractAddress }.contains(contract.address)
|
addedTokens.map { it.token.contractAddress }.contains(contract.address)
|
||||||
} else {
|
} else {
|
||||||
addedBlockchains.contains(blockchain)
|
addedBlockchains.contains(blockchain)
|
||||||
}
|
}
|
||||||
val canBeRemoved = if (contract != null) {
|
val canBeRemoved = if (contract != null && contract.address != currency.symbol) {
|
||||||
!nonRemovableTokens.contains(contract.address)
|
!nonRemovableTokens.contains(contract.address)
|
||||||
} else {
|
} else {
|
||||||
!nonRemovableBlockchains.contains(blockchain)
|
!nonRemovableBlockchains.contains(blockchain)
|
||||||
|
|
@ -146,7 +149,8 @@ fun ExpandedCurrencyItem(
|
||||||
blockchain = blockchain, allowToAdd = allowToAdd,
|
blockchain = blockchain, allowToAdd = allowToAdd,
|
||||||
added = added,
|
added = added,
|
||||||
canBeRemoved = canBeRemoved,
|
canBeRemoved = canBeRemoved,
|
||||||
onAddCurrencyToggled = onAddCurrencyToggled
|
onAddCurrencyToggled = onAddCurrencyToggled,
|
||||||
|
onNetworkItemClicked = onNetworkItemClicked,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ fun ListOfCurrencies(
|
||||||
addedBlockchains: List<Blockchain>,
|
addedBlockchains: List<Blockchain>,
|
||||||
searchInput: String,
|
searchInput: String,
|
||||||
allowToAdd: Boolean,
|
allowToAdd: Boolean,
|
||||||
onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit
|
onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit,
|
||||||
|
onNetworkItemClicked: (ContractAddress) -> Unit
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val expandedCurrencies = remember { mutableStateOf(listOf("")) }
|
val expandedCurrencies = remember { mutableStateOf(listOf("")) }
|
||||||
|
|
@ -59,7 +60,8 @@ fun ListOfCurrencies(
|
||||||
allowToAdd = allowToAdd,
|
allowToAdd = allowToAdd,
|
||||||
expanded = expandedCurrencies.value.contains(currency.id),
|
expanded = expandedCurrencies.value.contains(currency.id),
|
||||||
onCurrencyClick = onCurrencyClick,
|
onCurrencyClick = onCurrencyClick,
|
||||||
onAddCurrencyToggled = onAddCurrencyToggled
|
onAddCurrencyToggled = onAddCurrencyToggled,
|
||||||
|
onNetworkItemClicked = onNetworkItemClicked
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.tangem.tap.features.tokens.ui.compose
|
package com.tangem.tap.features.tokens.ui.compose
|
||||||
|
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.material.Switch
|
import androidx.compose.material.Switch
|
||||||
|
|
@ -21,19 +23,27 @@ import com.tangem.tap.common.extensions.getNetworkName
|
||||||
import com.tangem.tap.common.extensions.getRoundIconRes
|
import com.tangem.tap.common.extensions.getRoundIconRes
|
||||||
import com.tangem.tap.domain.tokens.Contract
|
import com.tangem.tap.domain.tokens.Contract
|
||||||
import com.tangem.tap.domain.tokens.Currency
|
import com.tangem.tap.domain.tokens.Currency
|
||||||
|
import com.tangem.tap.features.tokens.redux.ContractAddress
|
||||||
import com.tangem.tap.features.tokens.redux.TokenWithBlockchain
|
import com.tangem.tap.features.tokens.redux.TokenWithBlockchain
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun NetworkItem(
|
fun NetworkItem(
|
||||||
currency: Currency, contract: Contract?,
|
currency: Currency, contract: Contract?,
|
||||||
blockchain: Blockchain, allowToAdd: Boolean,
|
blockchain: Blockchain, allowToAdd: Boolean,
|
||||||
added: Boolean, canBeRemoved: Boolean,
|
added: Boolean, canBeRemoved: Boolean,
|
||||||
onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit
|
onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit,
|
||||||
|
onNetworkItemClicked: (ContractAddress) -> Unit
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
val isBlockchain = contract == null || contract.address == currency.symbol
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
.combinedClickable {
|
||||||
|
if (contract != null) onNetworkItemClicked(contract.address)
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
SubcomposeAsyncImage(
|
SubcomposeAsyncImage(
|
||||||
model = if (added) blockchain.getRoundIconRes() else blockchain.getGreyedOutIconRes(),
|
model = if (added) blockchain.getRoundIconRes() else blockchain.getGreyedOutIconRes(),
|
||||||
|
|
@ -46,10 +56,12 @@ fun NetworkItem(
|
||||||
.size(20.dp)
|
.size(20.dp)
|
||||||
.align(Alignment.CenterVertically)
|
.align(Alignment.CenterVertically)
|
||||||
)
|
)
|
||||||
Row(modifier = Modifier
|
Row(
|
||||||
.fillMaxHeight()
|
modifier = Modifier
|
||||||
.weight(1f)
|
.fillMaxHeight()
|
||||||
.align(Alignment.CenterVertically)) {
|
.weight(1f)
|
||||||
|
.align(Alignment.CenterVertically)
|
||||||
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = blockchain.name.uppercase(),
|
text = blockchain.name.uppercase(),
|
||||||
fontSize = 13.sp,
|
fontSize = 13.sp,
|
||||||
|
|
@ -58,30 +70,43 @@ fun NetworkItem(
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.size(3.dp))
|
Spacer(modifier = Modifier.size(3.dp))
|
||||||
Text(
|
Text(
|
||||||
text = if (contract != null) blockchain.getNetworkName().uppercase() else "MAIN",
|
text = if (isBlockchain) "MAIN" else blockchain.getNetworkName().uppercase(),
|
||||||
fontSize = 13.sp,
|
fontSize = 13.sp,
|
||||||
fontWeight = FontWeight.Normal,
|
fontWeight = FontWeight.Normal,
|
||||||
color = if (contract != null) Color(0xFF8E8E93) else Color(0xFF1ACE80),
|
color = if (!isBlockchain) Color(0xFF8E8E93) else Color(0xFF1ACE80),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val token = if (contract != null) {
|
if (allowToAdd) {
|
||||||
Token(
|
val token = if (!isBlockchain) {
|
||||||
name = currency.name, symbol = currency.symbol, contractAddress = contract.address,
|
Token(
|
||||||
decimals = contract.decimalCount,
|
id = currency.id,
|
||||||
|
name = currency.name,
|
||||||
|
symbol = currency.symbol,
|
||||||
|
contractAddress = contract!!.address,
|
||||||
|
decimals = contract.decimalCount,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
val tokenWithBlockchain =
|
||||||
|
token?.let { TokenWithBlockchain(token, contract!!.blockchain) }
|
||||||
|
|
||||||
|
val currencyToSave = if (isBlockchain && contract != null) {
|
||||||
|
currency.copy(id = contract.networkId)
|
||||||
|
} else {
|
||||||
|
currency
|
||||||
|
}
|
||||||
|
|
||||||
|
Switch(
|
||||||
|
checked = added,
|
||||||
|
enabled = canBeRemoved,
|
||||||
|
onCheckedChange = { onAddCurrencyToggled(currencyToSave, tokenWithBlockchain) },
|
||||||
|
modifier = Modifier.padding(start = 16.dp, end = 16.dp),
|
||||||
|
colors = SwitchDefaults.colors(
|
||||||
|
checkedThumbColor = Color(0xFF1ACE80)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
val tokenWithBlockchain = token?.let { TokenWithBlockchain(token, contract!!.blockchain) }
|
|
||||||
if (allowToAdd) Switch(
|
|
||||||
checked = added,
|
|
||||||
enabled = canBeRemoved,
|
|
||||||
onCheckedChange = { onAddCurrencyToggled(currency, tokenWithBlockchain) },
|
|
||||||
modifier = Modifier.padding(start = 16.dp, end = 16.dp),
|
|
||||||
colors = SwitchDefaults.colors(
|
|
||||||
checkedThumbColor = Color(0xFF1ACE80)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -127,11 +127,7 @@ class MultiWalletMiddleware {
|
||||||
val coinAmount = wallet.amounts[AmountType.Coin]?.value
|
val coinAmount = wallet.amounts[AmountType.Coin]?.value
|
||||||
if (coinAmount != null && !coinAmount.isZero()) {
|
if (coinAmount != null && !coinAmount.isZero()) {
|
||||||
scope.launch(Dispatchers.Main) {
|
scope.launch(Dispatchers.Main) {
|
||||||
val blockchainNetwork = BlockchainNetwork(
|
val blockchainNetwork = BlockchainNetwork.fromWalletManager(walletManager)
|
||||||
wallet.blockchain,
|
|
||||||
null,
|
|
||||||
walletManager.cardTokens.toList()
|
|
||||||
)
|
|
||||||
if (walletState?.getWalletData(blockchainNetwork) == null) {
|
if (walletState?.getWalletData(blockchainNetwork) == null) {
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
WalletAction.MultiWallet.AddBlockchain(
|
WalletAction.MultiWallet.AddBlockchain(
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import com.tangem.blockchain.common.Token
|
||||||
import com.tangem.tap.common.extensions.getString
|
import com.tangem.tap.common.extensions.getString
|
||||||
import com.tangem.tap.common.extensions.loadCurrenciesIcon
|
import com.tangem.tap.common.extensions.loadCurrenciesIcon
|
||||||
import com.tangem.tap.common.extensions.show
|
import com.tangem.tap.common.extensions.show
|
||||||
|
import com.tangem.tap.domain.TapWorkarounds.derivationStyle
|
||||||
import com.tangem.tap.features.wallet.redux.Currency
|
import com.tangem.tap.features.wallet.redux.Currency
|
||||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||||
import com.tangem.tap.features.wallet.redux.WalletData
|
import com.tangem.tap.features.wallet.redux.WalletData
|
||||||
|
|
@ -26,7 +27,11 @@ class WalletAdapter
|
||||||
return currentList[position].currencyData.currencySymbol?.hashCode()?.toLong() ?: 0
|
return currentList[position].currencyData.currencySymbol?.hashCode()?.toLong() ?: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fun submitList(list: List<WalletData>, primaryBlockchain: Blockchain?, primaryToken: Token? = null) {
|
fun submitList(
|
||||||
|
list: List<WalletData>,
|
||||||
|
primaryBlockchain: Blockchain?,
|
||||||
|
primaryToken: Token? = null
|
||||||
|
) {
|
||||||
// We used this method to sort the list of currencies. Sorting is disabled for now.
|
// We used this method to sort the list of currencies. Sorting is disabled for now.
|
||||||
super.submitList(list)
|
super.submitList(list)
|
||||||
}
|
}
|
||||||
|
|
@ -44,21 +49,22 @@ class WalletAdapter
|
||||||
|
|
||||||
object DiffUtilCallback : DiffUtil.ItemCallback<WalletData>() {
|
object DiffUtilCallback : DiffUtil.ItemCallback<WalletData>() {
|
||||||
override fun areContentsTheSame(
|
override fun areContentsTheSame(
|
||||||
oldItem: WalletData, newItem: WalletData
|
oldItem: WalletData, newItem: WalletData
|
||||||
) = oldItem == newItem
|
) = oldItem == newItem
|
||||||
|
|
||||||
override fun areItemsTheSame(
|
override fun areItemsTheSame(
|
||||||
oldItem: WalletData, newItem: WalletData
|
oldItem: WalletData, newItem: WalletData
|
||||||
) = oldItem == newItem
|
) = oldItem == newItem
|
||||||
}
|
}
|
||||||
|
|
||||||
class WalletsViewHolder(val binding: ItemCurrencyWalletBinding) :
|
class WalletsViewHolder(val binding: ItemCurrencyWalletBinding) :
|
||||||
RecyclerView.ViewHolder(binding.root) {
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
fun bind(wallet: WalletData) = with(binding) {
|
fun bind(wallet: WalletData) = with(binding) {
|
||||||
tvCurrency.text = wallet.currencyData.currency
|
tvCurrency.text = wallet.currencyData.currency
|
||||||
tvAmount.text = wallet.currencyData.amountFormatted?.takeWhile { !it.isWhitespace() }
|
tvAmount.text = wallet.currencyData.amountFormatted?.takeWhile { !it.isWhitespace() }
|
||||||
tvCurrencySymbol.text = wallet.currencyData.amountFormatted?.takeLastWhile { !it.isWhitespace() }
|
tvCurrencySymbol.text =
|
||||||
|
wallet.currencyData.amountFormatted?.takeLastWhile { !it.isWhitespace() }
|
||||||
tvAmountFiat.text = wallet.currencyData.fiatAmountFormatted
|
tvAmountFiat.text = wallet.currencyData.fiatAmountFormatted
|
||||||
tvExchangeRate.text = wallet.fiatRateString
|
tvExchangeRate.text = wallet.fiatRateString
|
||||||
cardWallet.setOnClickListener {
|
cardWallet.setOnClickListener {
|
||||||
|
|
@ -67,6 +73,11 @@ class WalletAdapter
|
||||||
val blockchain = wallet.currency.blockchain
|
val blockchain = wallet.currency.blockchain
|
||||||
val token = (wallet.currency as? Currency.Token)?.token
|
val token = (wallet.currency as? Currency.Token)?.token
|
||||||
|
|
||||||
|
val isCustom =
|
||||||
|
wallet.currency.isCustomCurrency(store.state.globalState.scanResponse?.card?.derivationStyle)
|
||||||
|
tvExchangeRate.show(!isCustom)
|
||||||
|
tvCustomCurrency.show(isCustom)
|
||||||
|
|
||||||
Picasso.get().loadCurrenciesIcon(
|
Picasso.get().loadCurrenciesIcon(
|
||||||
imageView = ivCurrency,
|
imageView = ivCurrency,
|
||||||
textView = tvTokenLetter,
|
textView = tvTokenLetter,
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,21 @@
|
||||||
app:layout_constraintTop_toTopOf="@id/guideline"
|
app:layout_constraintTop_toTopOf="@id/guideline"
|
||||||
tools:text="USD 3 588" />
|
tools:text="USD 3 588" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_custom_currency"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:paddingStart="4dp"
|
||||||
|
android:paddingEnd="4dp"
|
||||||
|
android:textColor="@color/darkGray2"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:background="@drawable/shape_rectangle_rounded_4"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/iv_currency"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/guideline"
|
||||||
|
android:text="@string/common_custom" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tv_status_error_message"
|
android:id="@+id/tv_status_error_message"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
|
|
||||||
|
|
@ -38,5 +38,9 @@
|
||||||
<string name="token_details_send_blocked_fee_format">Not enough funds for fee on your %s wallet to send a transaction. Top up your %s wallet first.</string>
|
<string name="token_details_send_blocked_fee_format">Not enough funds for fee on your %s wallet to send a transaction. Top up your %s wallet first.</string>
|
||||||
|
|
||||||
<string name="currency_subtitle_expanded">Available networks</string>
|
<string name="currency_subtitle_expanded">Available networks</string>
|
||||||
|
<string name="alert_manage_tokens_addresses_message">Note that tokens on different networks have different addresses. Double check that your address matches the network when you transfer funds.</string>
|
||||||
|
<string name="contract_address_copied_message">Contract address copied!</string>
|
||||||
|
|
||||||
|
<string name="common_custom">Custom</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -38,4 +38,9 @@
|
||||||
<string name="token_details_send_blocked_fee_format">Not enough funds for fee on your %s wallet to send a transaction. Top up your %s wallet first.</string>
|
<string name="token_details_send_blocked_fee_format">Not enough funds for fee on your %s wallet to send a transaction. Top up your %s wallet first.</string>
|
||||||
|
|
||||||
<string name="currency_subtitle_expanded">Available networks</string>
|
<string name="currency_subtitle_expanded">Available networks</string>
|
||||||
|
<string name="alert_manage_tokens_addresses_message">Note that tokens on different networks have different addresses. Double check that your address matches the network when you transfer funds.</string>
|
||||||
|
<string name="contract_address_copied_message">Contract address copied!</string>
|
||||||
|
|
||||||
|
<string name="common_custom">Custom</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -38,5 +38,9 @@
|
||||||
<string name="token_details_send_blocked_fee_format">Not enough funds for fee on your %s wallet to send a transaction. Top up your %s wallet first.</string>
|
<string name="token_details_send_blocked_fee_format">Not enough funds for fee on your %s wallet to send a transaction. Top up your %s wallet first.</string>
|
||||||
|
|
||||||
<string name="currency_subtitle_expanded">Available networks</string>
|
<string name="currency_subtitle_expanded">Available networks</string>
|
||||||
|
<string name="alert_manage_tokens_addresses_message">Note that tokens on different networks have different addresses. Double check that your address matches the network when you transfer funds.</string>
|
||||||
|
<string name="contract_address_copied_message">Contract address copied!</string>
|
||||||
|
|
||||||
|
<string name="common_custom">Custom</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -38,4 +38,9 @@
|
||||||
<string name="token_details_send_blocked_fee_format">Недостаточно средств для комиссии на вашем %s кошельке для отправки транзакции. Сначала пополните свой %s кошелек.</string>
|
<string name="token_details_send_blocked_fee_format">Недостаточно средств для комиссии на вашем %s кошельке для отправки транзакции. Сначала пополните свой %s кошелек.</string>
|
||||||
|
|
||||||
<string name="currency_subtitle_expanded">Доступные сети</string>
|
<string name="currency_subtitle_expanded">Доступные сети</string>
|
||||||
|
<string name="alert_manage_tokens_addresses_message">Внимание! Валюты на разных сетях имеют разные адреса. Убедитесь, что адрес соответствует сети, в которой вы отправляете средства.</string>
|
||||||
|
<string name="contract_address_copied_message">Адрес контракта скопирован!</string>
|
||||||
|
|
||||||
|
<string name="common_custom">Пользовательский</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -38,4 +38,9 @@
|
||||||
<string name="token_details_send_blocked_fee_format">Not enough funds for fee on your %s wallet to send a transaction. Top up your %s wallet first.</string>
|
<string name="token_details_send_blocked_fee_format">Not enough funds for fee on your %s wallet to send a transaction. Top up your %s wallet first.</string>
|
||||||
|
|
||||||
<string name="currency_subtitle_expanded">Available networks</string>
|
<string name="currency_subtitle_expanded">Available networks</string>
|
||||||
|
<string name="alert_manage_tokens_addresses_message">Note that tokens on different networks have different addresses. Double check that your address matches the network when you transfer funds.</string>
|
||||||
|
<string name="contract_address_copied_message">Contract address copied!</string>
|
||||||
|
|
||||||
|
<string name="common_custom">Custom</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
ext.versions = [
|
ext.versions = [
|
||||||
kotlin : '1.6.10',
|
kotlin : '1.6.10',
|
||||||
build_gradle: '7.0.4',
|
build_gradle: '7.1.3',
|
||||||
]
|
]
|
||||||
|
|
|
||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue