Updated on 2026-08-14

This commit is contained in:
Tangem 2022-03-29 21:01:29 +04:00
parent 040f53e52e
commit 2f1e813058
74 changed files with 1731 additions and 22861 deletions

View file

@ -123,7 +123,11 @@ dependencies {
implementation 'com.squareup.retrofit2:converter-moshi:2.6.0' implementation 'com.squareup.retrofit2:converter-moshi:2.6.0'
implementation 'com.squareup.moshi:moshi:1.12.0' implementation 'com.squareup.moshi:moshi:1.12.0'
implementation "com.squareup.moshi:moshi-kotlin:1.12.0" implementation "com.squareup.moshi:moshi-kotlin:1.12.0"
implementation 'com.squareup.okhttp3:logging-interceptor:4.2.2'
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.3"))
implementation("com.squareup.okhttp3:okhttp")
implementation("com.squareup.okhttp3:logging-interceptor")
// //
// //Crypto // //Crypto
implementation "com.madgag.spongycastle:core:1.58.0.0" implementation "com.madgag.spongycastle:core:1.58.0.0"
@ -142,11 +146,17 @@ dependencies {
//Compose //Compose
implementation 'androidx.activity:activity-compose:1.4.0' implementation 'androidx.activity:activity-compose:1.4.0'
implementation 'androidx.compose.material:material:1.1.0' implementation 'androidx.compose.material:material:1.1.1'
implementation 'androidx.compose.animation:animation:1.1.0' implementation 'androidx.compose.animation:animation:1.1.1'
implementation 'androidx.compose.ui:ui-tooling:1.1.0' implementation 'androidx.compose.foundation:foundation:1.1.1'
implementation 'androidx.compose.foundation:foundation-layout:1.1.1'
implementation 'androidx.compose.ui:ui:1.1.1'
implementation 'androidx.compose.ui:ui-tooling:1.1.1'
implementation "com.google.accompanist:accompanist-appcompat-theme:0.23.0" implementation "com.google.accompanist:accompanist-appcompat-theme:0.23.0"
implementation("io.coil-kt:coil:2.0.0-rc01")
implementation("io.coil-kt:coil-compose:2.0.0-rc01")
implementation 'com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.6' implementation 'com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.6'
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'

File diff suppressed because it is too large Load diff

View file

@ -1,26 +0,0 @@
[
{
"decimalCount": 18,
"symbol": "WEENUS",
"name": "Weenus",
"contractAddress": "0xaFF4481D10270F50f203E0763e2597776068CBc5"
},
{
"decimalCount": 18,
"symbol": "XEENUS",
"name": "Xeenus",
"contractAddress": "0x022E292b44B5a146F2e8ee36Ff44D3dd863C915c"
},
{
"decimalCount": 8,
"symbol": "YEENUS",
"name": "Yeenus",
"contractAddress": "0xc6fDe3FD2Cc2b173aEC24cc3f267cb3Cd78a26B7"
},
{
"decimalCount": 0,
"symbol": "ZEENUS",
"name": "Zeenus",
"contractAddress": "0x1f9061B953bBa0E36BF50F21876132DcF276fC6e"
}
]

View file

@ -0,0 +1,369 @@
{
"tokens" : [
{
"id" : "polygon/test",
"symbol" : "MATIC",
"name" : "Polygon",
"contracts" : [
{
"networkId" : "polygon-pos",
"address" : "0x0000000000000000000000000000000000001010",
"decimalCount" : 18
}
]
},
{
"id" : "Dai Stablecoin-DAI",
"symbol" : "DAI",
"name" : "Dai Stablecoin",
"contracts" : [
{
"networkId" : "polygon-pos",
"address" : "0xcB1e72786A6eb3b44C2a2429e317c8a2462CFeb1",
"decimalCount" : 18
},
{
"networkId" : "binance-smart-chain",
"address" : "0xec5dcb5dbf4b114c9d0f65bccab49ec54f6a0867",
"decimalCount" : 18
},
{
"networkId" : "binance-smart-chain",
"address" : "0x8a9424745056eb399fd19a0ec26a14316684e274",
"decimalCount" : 18
}
]
},
{
"id" : "Dummy ERC20-DERC20",
"symbol" : "DERC20",
"name" : "Dummy ERC20",
"contracts" : [
{
"networkId" : "polygon-pos",
"address" : "0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1",
"decimalCount" : 18
}
]
},
{
"id" : "Ether-ETH",
"symbol" : "ETH",
"name" : "Ether",
"contracts" : [
{
"networkId" : "polygon-pos",
"address" : "0x714550C2C1Ea08688607D86ed8EeF4f5E4F22323",
"decimalCount" : 18
},
{
"networkId" : "binance-smart-chain",
"address" : "0xd66c6b4f0be8ce5b39d52e0fd1344c389929b378",
"decimalCount" : 18
}
]
},
{
"id" : "Test Token-TST",
"symbol" : "TST",
"name" : "Test Token",
"contracts" : [
{
"networkId" : "polygon-pos",
"address" : "0x2d7882bedcbfddce29ba99965dd3cdf7fcb10a1e",
"decimalCount" : 18
}
]
},
{
"id" : "Tether USD-USDT",
"symbol" : "USDT",
"name" : "Tether USD",
"contracts" : [
{
"networkId" : "polygon-pos",
"address" : "0x3813e82e6f7098b9583FC0F33a962D02018B6803",
"decimalCount" : 6
},
{
"networkId" : "binance-smart-chain",
"address" : "0x337610d27c682e347c9cd60bd4b3b107c9d34ddd",
"decimalCount" : 18
},
{
"networkId" : "binance-smart-chain",
"address" : "0x7ef95a0fee0dd31b22626fa2e10ee6a223f8a684",
"decimalCount" : 18
}
]
},
{
"id" : "Wrapped Ether-WETH",
"symbol" : "WETH",
"name" : "Wrapped Ether",
"contracts" : [
{
"networkId" : "polygon-pos",
"address" : "0xA6FA4fB5f76172d178d61B04b0ecd319C5d1C0aa",
"decimalCount" : 18
}
]
},
{
"id" : "Wrapped Matic-WMATIC",
"symbol" : "WMATIC",
"name" : "Wrapped Matic",
"contracts" : [
{
"networkId" : "polygon-pos",
"address" : "0xd0A1E359811322d97991E03f863a0C30C2cF029C",
"decimalCount" : 18
}
]
},
{
"id" : "solana/test",
"symbol" : "SOL",
"name" : "Solana",
"contracts" : [
]
},
{
"id" : "Tangem Coin A-TCA",
"symbol" : "TCA",
"name" : "Tangem Coin A",
"contracts" : [
{
"networkId" : "solana",
"address" : "22PTNbX31Zuztd6nD82fC8nQdT2hUfWv9XWXKuDkrFqR",
"decimalCount" : 9
}
]
},
{
"id" : "Tangem Coin B-TCB",
"symbol" : "TCB",
"name" : "Tangem Coin B",
"contracts" : [
{
"networkId" : "solana",
"address" : "HmSghNPg6KCk711YJA92aPejt8auyFkvmaED6jbHfUs4",
"decimalCount" : 9
}
]
},
{
"id" : "binance/test",
"symbol" : "BNB",
"name" : "Binance",
"contracts" : [
]
},
{
"id" : "Hemster - 452-HEM",
"symbol" : "HEM",
"name" : "Hemster - 452",
"contracts" : [
{
"networkId" : "binancecoin",
"address" : "HEM-452",
"decimalCount" : 8
}
]
},
{
"id" : "bsc/test",
"symbol" : "BNB",
"name" : "Bsc",
"contracts" : [
]
},
{
"id" : "Binance-Peg BTCB Token-BTCB",
"symbol" : "BTCB",
"name" : "Binance-Peg BTCB Token",
"contracts" : [
{
"networkId" : "binance-smart-chain",
"address" : "0x6ce8da28e2f864420840cf74474eff5fd80e65b8",
"decimalCount" : 18
}
]
},
{
"id" : "Binance-Peg BUSD Token-BUSD",
"symbol" : "BUSD",
"name" : "Binance-Peg BUSD Token",
"contracts" : [
{
"networkId" : "binance-smart-chain",
"address" : "0xed24fc36d5ee211ea25a80239fb8c4cfd80f12ee",
"decimalCount" : 18
}
]
},
{
"id" : "Binance-Peg USDC Token-USDC",
"symbol" : "USDC",
"name" : "Binance-Peg USDC Token",
"contracts" : [
{
"networkId" : "binance-smart-chain",
"address" : "0x64544969ed7ebf5f083679233325356ebe738930",
"decimalCount" : 18
}
]
},
{
"id" : "Binance-Peg XRP-XRP",
"symbol" : "XRP",
"name" : "Binance-Peg XRP",
"contracts" : [
{
"networkId" : "binance-smart-chain",
"address" : "0xa83575490d7df4e2f47b7d38ef351a2722ca45b9",
"decimalCount" : 18
}
]
},
{
"id" : "ethereum/test",
"symbol" : "ETH",
"name" : "Ethereum",
"contracts" : [
]
},
{
"id" : "Weenus-WEENUS",
"symbol" : "WEENUS",
"name" : "Weenus",
"contracts" : [
{
"networkId" : "ethereum",
"address" : "0xaFF4481D10270F50f203E0763e2597776068CBc5",
"decimalCount" : 18
}
]
},
{
"id" : "Xeenus-XEENUS",
"symbol" : "XEENUS",
"name" : "Xeenus",
"contracts" : [
{
"networkId" : "ethereum",
"address" : "0x022E292b44B5a146F2e8ee36Ff44D3dd863C915c",
"decimalCount" : 18
}
]
},
{
"id" : "Yeenus-YEENUS",
"symbol" : "YEENUS",
"name" : "Yeenus",
"contracts" : [
{
"networkId" : "ethereum",
"address" : "0xc6fDe3FD2Cc2b173aEC24cc3f267cb3Cd78a26B7",
"decimalCount" : 8
}
]
},
{
"id" : "Zeenus-ZEENUS",
"symbol" : "ZEENUS",
"name" : "Zeenus",
"contracts" : [
{
"networkId" : "ethereum",
"address" : "0x1f9061B953bBa0E36BF50F21876132DcF276fC6e",
"decimalCount" : 0
}
]
},
{
"id" : "avalanche/test",
"symbol" : "AVAX",
"name" : "Avalanche",
"contracts" : [
]
},
{
"id" : "The Fuji stablecoin-FUJISTABLE",
"symbol" : "FUJISTABLE",
"name" : "The Fuji stablecoin",
"contracts" : [
{
"networkId" : "avalanche",
"address" : "0x2058ec2791dD28b6f67DB836ddf87534F4Bbdf22",
"decimalCount" : 6
}
]
},
{
"id" : "To the Moon-FUJIMOON",
"symbol" : "FUJIMOON",
"name" : "To the Moon",
"contracts" : [
{
"networkId" : "avalanche",
"address" : "0x97132C109c6816525F7f338DCb7435E1412A7668",
"decimalCount" : 9
}
]
},
{
"id" : "fantom/test",
"symbol" : "FTM",
"name" : "Fantom",
"contracts" : [
]
},
{
"id" : "Fantom USD-FUSD",
"symbol" : "FUSD",
"name" : "Fantom USD",
"contracts" : [
{
"networkId" : "fantom",
"address" : "0x91ea991bd52EE3C40EdA2509701d905e1Ee54074",
"decimalCount" : 18
}
]
},
{
"id" : "Wrapped Fantom-WFTM",
"symbol" : "WFTM",
"name" : "Wrapped Fantom",
"contracts" : [
{
"networkId" : "fantom",
"address" : "0xf1277d1Ed8AD466beddF92ef448A132661956621",
"decimalCount" : 18
}
]
},
{
"id" : "bitcoin/test",
"symbol" : "BTC",
"name" : "Bitcoin",
"contracts" : [
]
},
{
"id" : "stellar/test",
"symbol" : "XLM",
"name" : "Stellar",
"contracts" : [
]
}
]
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,37 @@
package com.tangem.tap.common.compose
import android.graphics.Rect
import android.view.ViewTreeObserver
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalView
sealed class Keyboard {
data class Opened(val height: Int): Keyboard()
object Closed : Keyboard()
}
@Composable
fun keyboardAsState(): State<Keyboard> {
val keyboardState: MutableState<Keyboard> = remember { mutableStateOf(Keyboard.Closed) }
val view = LocalView.current
DisposableEffect(view) {
val onGlobalListener = ViewTreeObserver.OnGlobalLayoutListener {
val rect = Rect()
view.getWindowVisibleDisplayFrame(rect)
val screenHeight = view.rootView.height
val keypadHeight = screenHeight - rect.bottom
keyboardState.value = if (keypadHeight > screenHeight * 0.15) {
Keyboard.Opened(keypadHeight)
} else {
Keyboard.Closed
}
}
view.viewTreeObserver.addOnGlobalLayoutListener(onGlobalListener)
onDispose {
view.viewTreeObserver.removeOnGlobalLayoutListener(onGlobalListener)
}
}
return keyboardState
}

View file

@ -21,4 +21,59 @@ fun Blockchain.getIconRes(): Int {
Blockchain.Stellar -> R.drawable.ic_stellar Blockchain.Stellar -> R.drawable.ic_stellar
else -> R.drawable.shape_circle else -> R.drawable.shape_circle
} }
}
@DrawableRes
fun Blockchain.getRoundIconRes(): Int {
return when (this) {
// Blockchain.Ducatus -> R.drawable.ic_ducatus
Blockchain.Bitcoin, Blockchain.BitcoinTestnet,-> R.drawable.ic_bitcoin_round
Blockchain.BitcoinCash -> R.drawable.ic_bitcoin_cash_round
Blockchain.Litecoin -> R.drawable.ic_litecoin_round
Blockchain.Ethereum, Blockchain.EthereumTestnet, -> R.drawable.ic_eth_round
Blockchain.RSK -> R.drawable.ic_rsk_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.XRP -> R.drawable.ic_xrp_round
Blockchain.Stellar -> R.drawable.ic_stellar_round
Blockchain.Avalanche, Blockchain.AvalancheTestnet -> R.drawable.ic_avalanche_round
Blockchain.Polygon, Blockchain.PolygonTestnet -> R.drawable.ic_polygon_round
Blockchain.Solana, Blockchain.SolanaTestnet -> R.drawable.ic_solana_round
Blockchain.Fantom, Blockchain.FantomTestnet -> R.drawable.ic_fantom_round
Blockchain.BSC, Blockchain.BSCTestnet -> R.drawable.ic_bsc_round
else -> R.drawable.ic_tangem_logo
}
}
@DrawableRes
fun Blockchain.getGreyedOutIconRes(): Int {
return when (this) {
// Blockchain.Ducatus -> R.drawable.ic_ducatus
Blockchain.Bitcoin, Blockchain.BitcoinTestnet,-> R.drawable.ic_bitcoin_no_color
Blockchain.BitcoinCash -> R.drawable.ic_bitcoin_cash_no_color
Blockchain.Litecoin -> R.drawable.ic_litecoin_no_color
Blockchain.Ethereum, Blockchain.EthereumTestnet, -> R.drawable.ic_eth_no_color
Blockchain.RSK -> R.drawable.ic_rsk_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.XRP -> R.drawable.ic_xrp_no_color
Blockchain.Stellar -> R.drawable.ic_stellar_no_color
Blockchain.Avalanche, Blockchain.AvalancheTestnet -> R.drawable.ic_avalanche_no_color
Blockchain.Polygon, Blockchain.PolygonTestnet -> R.drawable.ic_polygon_no_color
Blockchain.Solana, Blockchain.SolanaTestnet -> R.drawable.ic_solana_no_color
Blockchain.Fantom, Blockchain.FantomTestnet -> R.drawable.ic_fantom_no_color
Blockchain.BSC, Blockchain.BSCTestnet -> R.drawable.ic_bsc_no_color
else -> R.drawable.ic_tangem_logo
}
}
fun Blockchain.getNetworkName(): String {
return when (this) {
Blockchain.Ethereum, Blockchain.EthereumTestnet -> "ERC20"
Blockchain.BSC, Blockchain.BSCTestnet -> "BEP20"
Blockchain.Binance, Blockchain.BinanceTestnet -> "BEP2"
else -> ""
}
} }

View file

@ -6,6 +6,7 @@ import android.content.res.Resources
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.util.DisplayMetrics
import android.util.TypedValue import android.util.TypedValue
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -19,6 +20,7 @@ import androidx.fragment.app.Fragment
import com.google.android.material.card.MaterialCardView import com.google.android.material.card.MaterialCardView
import com.tangem.common.extensions.VoidCallback import com.tangem.common.extensions.VoidCallback
fun Fragment.getDrawable(@DrawableRes drawableResId: Int): Drawable? { fun Fragment.getDrawable(@DrawableRes drawableResId: Int): Drawable? {
return ContextCompat.getDrawable(requireContext(), drawableResId) return ContextCompat.getDrawable(requireContext(), drawableResId)
} }
@ -94,6 +96,13 @@ fun Context.dpToPixels(dp: Int): Int =
TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), this.resources.displayMetrics TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), this.resources.displayMetrics
).toInt() ).toInt()
fun Context.pixelsToDp(pixels: Int): Int {
return (pixels.toFloat() /
(resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT))
.toInt()
}
tailrec fun Context?.getActivity(): Activity? = this as? Activity tailrec fun Context?.getActivity(): Activity? = this as? Activity
?: (this as? ContextWrapper)?.baseContext?.getActivity() ?: (this as? ContextWrapper)?.baseContext?.getActivity()

View file

@ -16,6 +16,7 @@ import com.tangem.tap.domain.extensions.setCustomIconUrl
import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.network.createMoshi import com.tangem.tap.network.createMoshi
import timber.log.Timber import timber.log.Timber
import java.util.*
class CurrenciesRepository(val context: Application) { class CurrenciesRepository(val context: Application) {
@ -29,6 +30,9 @@ class CurrenciesRepository(val context: Application) {
private val obsoleteTokensAdapter: JsonAdapter<List<ObsoleteTokenDao>> = moshi.adapter( private val obsoleteTokensAdapter: JsonAdapter<List<ObsoleteTokenDao>> = moshi.adapter(
Types.newParameterizedType(List::class.java, ObsoleteTokenDao::class.java) Types.newParameterizedType(List::class.java, ObsoleteTokenDao::class.java)
) )
private val currenciesAdapter : JsonAdapter<CurrenciesFromJson> =
moshi.adapter(CurrenciesFromJson::class.java)
fun loadCardCurrencies(cardId: String): CardCurrencies? { fun loadCardCurrencies(cardId: String): CardCurrencies? {
val blockchains = loadSavedBlockchains(cardId).toMutableSet() val blockchains = loadSavedBlockchains(cardId).toMutableSet()
@ -116,18 +120,10 @@ class CurrenciesRepository(val context: Application) {
} }
} }
fun getSupportedTokens(isTestNet: Boolean = false): List<Token> { fun getSupportedTokens(isTestNet: Boolean = false): List<Currency> {
val supportedTokens = if (isTestNet) { val fileName = if (isTestNet) "testnet_tokens" else "tokens"
getSupportedTokens().mapNotNull { it.getTestnetVersion() } val json = context.assets.readJsonFileToString(fileName)
} else { return currenciesAdapter.fromJson(json)!!.tokens.map { Currency.fromJsonObject(it) }
getSupportedTokens()
}
val blockchainTokens = supportedTokens.mapNotNull { blockchain ->
loadTokensJson(blockchain)?.let { fromJsonToTokensDao(it, blockchain) }
}
val tokens = blockchainTokens.flatten().map { it.toToken() }
return tokens
} }
private fun loadTokensJson(blockchain: Blockchain): String? { private fun loadTokensJson(blockchain: Blockchain): String? {
@ -142,7 +138,7 @@ class CurrenciesRepository(val context: Application) {
private fun getFileName(blockchain: Blockchain): String { private fun getFileName(blockchain: Blockchain): String {
return StringBuilder().apply { return StringBuilder().apply {
append(blockchain.id.toLowerCase().replace("/test", "")) append(blockchain.id.lowercase(Locale.getDefault()).replace("/test", ""))
append("_tokens") append("_tokens")
appendIf("_testnet") { blockchain.isTestnet() } appendIf("_testnet") { blockchain.isTestnet() }
}.toString() }.toString()

View file

@ -0,0 +1,134 @@
package com.tangem.tap.domain.tokens
import com.squareup.moshi.JsonClass
import com.tangem.blockchain.common.Blockchain
@JsonClass(generateAdapter = true)
data class CurrencyFromJson(
val id: String,
val name: String,
val symbol: String,
val contracts: List<ContractFromJson>? = null
)
@JsonClass(generateAdapter = true)
data class ContractFromJson(
val networkId: String,
val address: String,
val decimalCount: Int
)
@JsonClass(generateAdapter = true)
data class CurrenciesFromJson(
val imageHost: String,
val tokens: List<CurrencyFromJson>
)
fun List<ContractFromJson>.toContracts(): List<Contract> {
return map { Contract.fromJsonObject(it) }
}
data class Currency(
val id: String,
val name: String,
val symbol: String,
val iconUrl: String,
val contracts: List<Contract>?
) {
companion object {
fun fromJsonObject(currency: CurrencyFromJson): Currency {
return Currency(
id = currency.id,
name = currency.name,
symbol = currency.symbol,
iconUrl = getIconUrl(currency.id),
contracts = currency.contracts?.toContracts()
)
}
}
}
data class Contract(
val networkId: String,
val blockchain: Blockchain,
val address: String,
val decimalCount: Int,
val iconUrl: String,
) {
companion object {
fun fromJsonObject(contract: ContractFromJson): Contract {
return Contract(
networkId = contract.networkId,
blockchain = Blockchain.fromNetworkId(contract.networkId),
address = contract.address,
decimalCount = contract.decimalCount,
iconUrl = getIconUrl(contract.networkId)
)
}
}
}
fun getIconUrl(id: String): String {
return "https://s3.eu-central-1.amazonaws.com/tangem.api/coins/large/$id.png"
}
fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain {
return when (networkId) {
"avalanche" -> Blockchain.Avalanche
"binancecoin" -> Blockchain.Binance
"binance-smart-chain" -> Blockchain.BSC
"ethereum" -> Blockchain.Ethereum
"polygon-pos" -> Blockchain.Polygon
"solana" -> Blockchain.Solana
"fantom" -> Blockchain.Fantom
"bitcoin" -> Blockchain.Bitcoin
"bitcoin-cash" -> Blockchain.BitcoinCash
"cardano" -> Blockchain.CardanoShelley
"dogecoin" -> Blockchain.Dogecoin
"ducatus" -> Blockchain.Ducatus
"litecoin" -> Blockchain.Litecoin
"rsk" -> Blockchain.RSK
"stellar" -> Blockchain.Stellar
"tezos" -> Blockchain.Tezos
"ripple" -> Blockchain.XRP
else -> Blockchain.Unknown
}
}
fun Blockchain.toNetworkId(): String {
return when (this) {
Blockchain.Unknown -> "unknown"
Blockchain.Avalanche -> "avalaunch"
Blockchain.AvalancheTestnet -> "avalaunch"
Blockchain.Binance -> "binancecoin"
Blockchain.BinanceTestnet -> "binancecoin"
Blockchain.BSC -> "binance-smart-chain"
Blockchain.BSCTestnet -> "binance-smart-chain"
Blockchain.Bitcoin -> "bitcoin"
Blockchain.BitcoinTestnet -> "bitcoin"
Blockchain.BitcoinCash -> "bitcoin-cash"
Blockchain.BitcoinCashTestnet -> "bitcoin-cash"
Blockchain.Cardano -> "cardano"
Blockchain.CardanoShelley -> "cardano"
Blockchain.Dogecoin -> "dogecoin"
Blockchain.Ducatus -> "ducatus"
Blockchain.Ethereum -> "ethereum"
Blockchain.EthereumTestnet -> "ethereum"
Blockchain.Fantom -> "fantom"
Blockchain.FantomTestnet -> "fantom"
Blockchain.Litecoin -> "litecoin"
Blockchain.Polygon -> "matic-network"
Blockchain.PolygonTestnet -> "matic-networks"
Blockchain.RSK -> "rsk"
Blockchain.Stellar -> "stellar"
Blockchain.StellarTestnet -> "stellar"
Blockchain.Solana -> "solana"
Blockchain.SolanaTestnet -> "solana"
Blockchain.Tezos -> "tezos"
Blockchain.XRP -> "ripple"
}
}

View file

@ -7,10 +7,13 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.google.accompanist.appcompattheme.AppCompatTheme import com.google.accompanist.appcompattheme.AppCompatTheme
import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.home.compose.StoriesScreen import com.tangem.tap.features.home.compose.StoriesScreen
import com.tangem.tap.features.home.redux.HomeAction import com.tangem.tap.features.home.redux.HomeAction
import com.tangem.tap.features.home.redux.HomeState import com.tangem.tap.features.home.redux.HomeState
import com.tangem.tap.features.onboarding.products.wallet.redux.BackupAction import com.tangem.tap.features.onboarding.products.wallet.redux.BackupAction
import com.tangem.tap.features.tokens.redux.TokensAction
import com.tangem.tap.store import com.tangem.tap.store
import com.tangem.wallet.R import com.tangem.wallet.R
import org.rekotlin.StoreSubscriber import org.rekotlin.StoreSubscriber
@ -35,7 +38,12 @@ class HomeFragment : Fragment(R.layout.fragment_home), StoreSubscriber<HomeState
StoriesScreen( StoriesScreen(
homeState, homeState,
onScanButtonClick = { store.dispatch(HomeAction.ReadCard) }, onScanButtonClick = { store.dispatch(HomeAction.ReadCard) },
onShopButtonClick = { store.dispatch(HomeAction.GoToShop(getRegionProvider())) } onShopButtonClick = { store.dispatch(HomeAction.GoToShop(getRegionProvider())) },
onSearchTokensClick = {
store.dispatch(TokensAction.AllowToAddTokens(false))
store.dispatch(TokensAction.LoadCurrencies)
store.dispatch(NavigationAction.NavigateTo(AppScreen.AddTokens))
}
) )
} }
} }

View file

@ -4,6 +4,9 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -16,8 +19,12 @@ import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.tangem.tap.features.home.redux.HomeState import com.tangem.tap.features.home.redux.HomeState
import com.tangem.tap.features.wallet.redux.ProgressState import com.tangem.tap.features.wallet.redux.ProgressState
import com.tangem.wallet.R import com.tangem.wallet.R
@ -27,7 +34,8 @@ import kotlin.math.max
fun StoriesScreen( fun StoriesScreen(
homeState: MutableState<HomeState> = mutableStateOf(HomeState()), homeState: MutableState<HomeState> = mutableStateOf(HomeState()),
onScanButtonClick: () -> Unit, onScanButtonClick: () -> Unit,
onShopButtonClick: () -> Unit onShopButtonClick: () -> Unit,
onSearchTokensClick: () -> Unit,
) { ) {
val steps = 6 val steps = 6
val stepDuration = 8_000 val stepDuration = 8_000
@ -77,7 +85,8 @@ fun StoriesScreen(
} }
) )
Box( Box(
Modifier.weight(1f) Modifier
.weight(1f)
.fillMaxHeight() .fillMaxHeight()
.pointerInput(isPressed) { .pointerInput(isPressed) {
detectTapGestures( detectTapGestures(
@ -106,7 +115,7 @@ fun StoriesScreen(
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center, verticalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
Spacer(modifier = Modifier.size(24.dp)) Spacer(modifier = Modifier.size(24.dp))
StoriesProgressBar( StoriesProgressBar(
@ -137,15 +146,44 @@ fun StoriesScreen(
6 -> StoriesWalletForEveryone() 6 -> StoriesWalletForEveryone()
} }
} }
HomeButtons( Column(
isDarkBackground = isDarkBackground,
modifier = Modifier modifier = Modifier
.align(Alignment.BottomCenter) .align(Alignment.BottomCenter)
.padding(16.dp, 0.dp, 16.dp, 37.dp) .fillMaxWidth()
.fillMaxWidth(), ) {
onScanButtonClick = onScanButtonClick, if (currentStep.value == 4) Button(
onShopButtonClick = onShopButtonClick onClick = onSearchTokensClick,
) modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
.height(48.dp)
,
colors = ButtonDefaults.textButtonColors(
backgroundColor = Color.White,
contentColor = Color(0xFF080C10)
)
) {
Image(
painter = painterResource(id = R.drawable.ic_search),
contentDescription = null
)
Text(
text = stringResource(id = R.string.search_tokens_title),
fontWeight = FontWeight.Medium,
fontSize = 16.sp,
textAlign = TextAlign.Center
)
}
HomeButtons(
isDarkBackground = isDarkBackground,
modifier = Modifier
.padding(start = 16.dp, top = 0.dp, end = 16.dp, bottom = 37.dp)
.fillMaxWidth(),
onScanButtonClick = onScanButtonClick,
onShopButtonClick = onShopButtonClick
)
}
} }
} }
@ -153,5 +191,5 @@ fun StoriesScreen(
@Preview @Preview
@Composable @Composable
fun InstagramScreenPreview() { fun InstagramScreenPreview() {
StoriesScreen(onScanButtonClick = {}, onShopButtonClick = {}) StoriesScreen(onScanButtonClick = {}, onShopButtonClick = {}, onSearchTokensClick = {})
} }

View file

@ -1,89 +0,0 @@
package com.tangem.tap.features.tokens.redux
import androidx.annotation.StringRes
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.wallet.R
sealed class CurrencyListItem {
var isAdded: Boolean = false
var isLocked: Boolean = false
data class TokenListItem(val token: Token) : CurrencyListItem()
data class BlockchainListItem(val blockchain: Blockchain) : CurrencyListItem()
data class TitleListItem(
@StringRes val titleResId: Int,
var isContentShown: Boolean = true,
val blockchain: Blockchain? = null,
) : CurrencyListItem()
companion object {
fun createListOfCurrencies(
blockchains: List<Blockchain>,
tokens: List<Token>,
): List<CurrencyListItem> {
val blockchainsItemList = createBlockchainList(blockchains)
val tokenItemsLists = tokens.groupBy { it.blockchain }.map {
createTokensList(R.string.add_tokens_subtitle_format, it.key, it.value)
}
return blockchainsItemList + tokenItemsLists.flatten()
}
private fun createBlockchainList(blockchains: List<Blockchain>): List<CurrencyListItem> {
val blockchainsTitle = R.string.add_tokens_subtitle_blockchains
return listOf(TitleListItem(blockchainsTitle)) + blockchains.map { BlockchainListItem(it) }
}
private fun createTokensList(
@StringRes titleResId: Int,
blockchain: Blockchain,
tokens: List<Token>
): List<CurrencyListItem> {
val filteredTokens = tokens.filter {
it.blockchain == blockchain || it.blockchain == blockchain.getTestnetVersion()
}
val tokensListItem = filteredTokens.map { TokenListItem(it) }
return listOf(TitleListItem(titleResId, blockchain = blockchain)) + tokensListItem
}
}
}
fun List<CurrencyListItem>.removeTokensForBlockchain(blockchain: Blockchain): List<CurrencyListItem> {
return filterNot {
it is CurrencyListItem.TokenListItem && it.isTheSameOrTestnetBlockchain(blockchain)
}
}
fun List<CurrencyListItem>.addTokensForBlockchain(
blockchain: Blockchain, fullCurrenciesList: List<CurrencyListItem>,
): List<CurrencyListItem> {
val tokensToAdd = fullCurrenciesList.filter {
it is CurrencyListItem.TokenListItem && it.isTheSameOrTestnetBlockchain(blockchain)
}
val indexToInsert = indexOfFirst {
it is CurrencyListItem.TitleListItem && it.isTheSameOrTestnetBlockchain(blockchain)
} + 1
return this.toMutableList().apply { addAll(indexToInsert, tokensToAdd) }
}
fun List<CurrencyListItem>.toggleHeaderContentShownValue(blockchain: Blockchain) {
map {
if (it is CurrencyListItem.TitleListItem && it.isTheSameOrTestnetBlockchain(blockchain)) {
it.isContentShown = !it.isContentShown
}
}
}
// if you do not check the testNet blockchains, it will not collapse
private fun CurrencyListItem.isTheSameOrTestnetBlockchain(blockchain: Blockchain): Boolean {
return when (this) {
is CurrencyListItem.TitleListItem -> this.blockchain?.isTheSameOrTestnetBlockchain(blockchain) ?: false
is CurrencyListItem.BlockchainListItem -> this.blockchain.isTheSameOrTestnetBlockchain(blockchain)
is CurrencyListItem.TokenListItem -> this.token.blockchain.isTheSameOrTestnetBlockchain(blockchain)
}
}
private fun Blockchain.isTheSameOrTestnetBlockchain(blockchain: Blockchain): Boolean {
return this == blockchain || this == blockchain.getTestnetVersion()
}

View file

@ -1,6 +1,8 @@
package com.tangem.tap.features.tokens.redux package com.tangem.tap.features.tokens.redux
import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.tap.domain.tokens.Currency
import com.tangem.tap.features.wallet.redux.WalletData import com.tangem.tap.features.wallet.redux.WalletData
import org.rekotlin.Action import org.rekotlin.Action
@ -8,14 +10,17 @@ sealed class TokensAction : Action {
object ResetState : TokensAction() object ResetState : TokensAction()
data class AllowToAddTokens(val allow: Boolean) : TokensAction()
object LoadCurrencies : TokensAction() { object LoadCurrencies : TokensAction() {
data class Success(val currencies: List<CurrencyListItem>) : TokensAction() data class Success(val currencies: List<Currency>) : TokensAction()
} }
data class SetAddedCurrencies(val wallets: List<WalletData>) : TokensAction() data class SetAddedCurrencies(val wallets: List<WalletData>) : TokensAction()
data class SetNonRemovableCurrencies(val wallets: List<WalletData>) : TokensAction()
data class ToggleShowTokensForBlockchain(val isShown: Boolean, val blockchain: Blockchain) : TokensAction() data class SaveChanges(
object OpenAllTokens : TokensAction() val addedTokens: List<Token>,
val addedBlockchains: List<Blockchain>
data class SaveChanges(val addedItems: List<CurrencyListItem>) : TokensAction() ) : TokensAction()
} }

View file

@ -12,6 +12,7 @@ import com.tangem.tap.common.extensions.dispatchErrorNotification
import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.currenciesRepository import com.tangem.tap.currenciesRepository
import com.tangem.tap.domain.DELAY_SDK_DIALOG_CLOSE import com.tangem.tap.domain.DELAY_SDK_DIALOG_CLOSE
@ -33,6 +34,11 @@ class TokensMiddleware {
{ next -> { next ->
{ action -> { action ->
when (action) { when (action) {
is NavigationAction.NavigateTo -> {
if (action.screen == AppScreen.AddTokens) {
store.dispatch(TokensAction.LoadCurrencies)
}
}
is TokensAction.LoadCurrencies -> handleLoadCurrencies() is TokensAction.LoadCurrencies -> handleLoadCurrencies()
is TokensAction.SaveChanges -> handleSaveChanges(action) is TokensAction.SaveChanges -> handleSaveChanges(action)
} }
@ -42,34 +48,37 @@ class TokensMiddleware {
} }
private fun handleLoadCurrencies() { private fun handleLoadCurrencies() {
val scanResponse = store.state.globalState.scanResponse ?: return val scanResponse = store.state.globalState.scanResponse
val isTestcard = scanResponse.card.isTestCard val isTestcard = scanResponse?.card?.isTestCard ?: false
val currencies = currenciesRepository.getSupportedTokens(isTestcard)
val tokens = currenciesRepository.getSupportedTokens(isTestcard)
val blockchains = currenciesRepository.getBlockchains(
cardFirmware = scanResponse.card.firmwareVersion,
isTestNet = isTestcard
).sortedBy { it.fullName }
val currencies = CurrencyListItem.createListOfCurrencies(blockchains, tokens)
store.dispatch(TokensAction.LoadCurrencies.Success(currencies)) store.dispatch(TokensAction.LoadCurrencies.Success(currencies))
} }
private fun handleSaveChanges(action: TokensAction.SaveChanges) { private fun handleSaveChanges(action: TokensAction.SaveChanges) {
val scanResponse = store.state.globalState.scanResponse ?: return val scanResponse = store.state.globalState.scanResponse ?: return
val candidatesToAdd = action.addedItems val currentTokens = store.state.tokensState.addedWallets.toTokens()
if (candidatesToAdd.isEmpty()) return val currentBlockchains = store.state.tokensState.addedWallets.toBlockchains()
val blockchains = candidatesToAdd.filterIsInstance<CurrencyListItem.BlockchainListItem>() val blockchainsToAdd = action.addedBlockchains.filter { !currentBlockchains.contains(it) }
.map { it.blockchain } val blockchainsToRemove = currentBlockchains.filter { !action.addedBlockchains.contains(it) }
val tokens = candidatesToAdd.filterIsInstance<CurrencyListItem.TokenListItem>()
.map { it.token } val tokensToAdd = action.addedTokens.filter { !currentTokens.contains(it) }
if (blockchains.isEmpty() && tokens.isEmpty()) return val tokensToRemove = currentTokens.filter { !action.addedTokens.contains(it) }
removeCurrenciesIfNeeded(blockchainsToRemove, tokensToRemove)
if (tokensToAdd.isEmpty() && blockchainsToAdd.isEmpty()) {
store.dispatch(NavigationAction.PopBackTo())
return
}
if (scanResponse.supportsHdWallet()) { if (scanResponse.supportsHdWallet()) {
deriveMissingBlockchains(scanResponse, blockchains, tokens) deriveMissingBlockchains(scanResponse, blockchainsToAdd, tokensToAdd)
} else { } else {
submitAdd(blockchains, tokens) submitAdd(blockchainsToAdd, tokensToAdd)
store.dispatch(NavigationAction.PopBackTo()) store.dispatch(NavigationAction.PopBackTo())
} }
} }
@ -158,4 +167,22 @@ class TokensMiddleware {
WalletAction.MultiWallet.AddToken(it) WalletAction.MultiWallet.AddToken(it)
}).forEach { store.dispatchOnMain(it) } }).forEach { store.dispatchOnMain(it) }
} }
private fun removeCurrenciesIfNeeded(blockchains: List<Blockchain>, tokens: List<Token>) {
if (tokens.isNotEmpty()) {
tokens.forEach { token ->
store.state.walletState.getWalletData(token)?.let {
store.dispatch(WalletAction.MultiWallet.RemoveWallet(it))
}
}
}
if (blockchains.isNotEmpty()) {
blockchains.forEach { blockchain ->
store.state.walletState.getWalletData(blockchain)?.let {
store.dispatch(WalletAction.MultiWallet.RemoveWallet(it))
}
}
}
}
} }

View file

@ -1,9 +1,6 @@
package com.tangem.tap.features.tokens.redux package com.tangem.tap.features.tokens.redux
import com.tangem.tap.common.redux.AppState 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 import org.rekotlin.Action
class TokensReducer { class TokensReducer {
@ -19,35 +16,25 @@ private fun internalReduce(action: Action, state: AppState): TokensState {
return when (action) { return when (action) {
is TokensAction.ResetState -> TokensState() is TokensAction.ResetState -> TokensState()
is TokensAction.LoadCurrencies.Success -> { is TokensAction.LoadCurrencies.Success -> {
tokensState.copy(currencies = action.currencies, shownCurrencies = action.currencies) tokensState.copy(currencies = action.currencies)
} }
is TokensAction.SetAddedCurrencies -> { is TokensAction.SetAddedCurrencies -> {
tokensState.copy(addedCurrencies = action.wallets.toCardCurrencies()) tokensState.copy(
addedBlockchains = action.wallets.toBlockchains(),
addedTokens = action.wallets.toTokens(),
addedWallets = action.wallets,
)
} }
is TokensAction.ToggleShowTokensForBlockchain -> { is TokensAction.SetNonRemovableCurrencies -> {
if (action.isShown) { tokensState.copy(
val shownCurrencies = tokensState.shownCurrencies nonRemovableBlockchains = action.wallets.toBlockchains(),
.removeTokensForBlockchain(action.blockchain) nonRemovableTokens = action.wallets.toTokensContractAddresses(),
shownCurrencies.toggleHeaderContentShownValue(action.blockchain) )
tokensState.copy(shownCurrencies = shownCurrencies)
} else {
val shownCurrencies = tokensState.shownCurrencies
.addTokensForBlockchain(action.blockchain, tokensState.currencies)
shownCurrencies.toggleHeaderContentShownValue(action.blockchain)
tokensState.copy(shownCurrencies = shownCurrencies)
}
} }
is TokensAction.OpenAllTokens -> {
val shownCurrencies = tokensState.currencies is TokensAction.AllowToAddTokens -> {
shownCurrencies.forEach { if (it is CurrencyListItem.TitleListItem) it.isContentShown = true} tokensState.copy(allowToAdd = action.allow)
tokensState.copy(shownCurrencies = tokensState.currencies)
} }
else -> tokensState else -> tokensState
} }
}
private fun List<WalletData>.toCardCurrencies(): CardCurrencies {
val tokens = mapNotNull { (it.currency as? Currency.Token)?.token }.distinct()
val blockchains = mapNotNull { (it.currency as? Currency.Blockchain)?.blockchain }.distinct()
return CardCurrencies(tokens = tokens, blockchains = blockchains)
} }

View file

@ -1,18 +1,31 @@
package com.tangem.tap.features.tokens.redux package com.tangem.tap.features.tokens.redux
import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token import com.tangem.blockchain.common.Token
import com.tangem.tap.domain.tokens.CardCurrencies import com.tangem.tap.domain.tokens.Currency
import com.tangem.tap.features.wallet.redux.WalletData
import org.rekotlin.StateType import org.rekotlin.StateType
data class TokensState( data class TokensState(
val addedTokens: LinkedHashSet<TokenWithAmount> = LinkedHashSet(), val addedWallets: List<WalletData> = emptyList(),
val addedCurrencies: CardCurrencies? = null, val addedTokens: List<Token> = emptyList(),
val currencies: List<CurrencyListItem> = emptyList(), val addedBlockchains: List<Blockchain> = emptyList(),
val shownCurrencies: List<CurrencyListItem> = emptyList(), val nonRemovableTokens: List<ContractAddress> = emptyList(),
val nonRemovableBlockchains: List<Blockchain> = emptyList(),
val currencies: List<Currency> = emptyList(),
val allowToAdd: Boolean = true
) : StateType ) : StateType
data class TokenWithAmount( typealias ContractAddress = String
val token: Token,
val amount: Amount? = null fun List<WalletData>.toTokensContractAddresses(): List<ContractAddress> {
) return mapNotNull { (it.currency as? com.tangem.tap.features.wallet.redux.Currency.Token)?.token?.contractAddress }.distinct()
}
fun List<WalletData>.toTokens(): List<Token> {
return mapNotNull { (it.currency as? com.tangem.tap.features.wallet.redux.Currency.Token)?.token }.distinct()
}
fun List<WalletData>.toBlockchains(): List<Blockchain> {
return mapNotNull { (it.currency as? com.tangem.tap.features.wallet.redux.Currency.Blockchain)?.blockchain }.distinct()
}

View file

@ -8,15 +8,17 @@ import android.view.View
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
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.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.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.adapters.CurrenciesAdapter import com.tangem.tap.features.tokens.ui.compose.CurrenciesScreen
import com.tangem.tap.mainScope import com.tangem.tap.mainScope
import com.tangem.tap.store import com.tangem.tap.store
import com.tangem.wallet.R import com.tangem.wallet.R
@ -27,10 +29,11 @@ import org.rekotlin.StoreSubscriber
class AddTokensFragment : Fragment(R.layout.fragment_add_tokens), class AddTokensFragment : Fragment(R.layout.fragment_add_tokens),
StoreSubscriber<TokensState> { StoreSubscriber<TokensState> {
private lateinit var viewAdapter: CurrenciesAdapter
private val binding: FragmentAddTokensBinding by viewBinding(FragmentAddTokensBinding::bind) private val binding: FragmentAddTokensBinding by viewBinding(FragmentAddTokensBinding::bind)
private var tokensState: MutableState<TokensState> = mutableStateOf(store.state.tokensState)
private var searchInput = mutableStateOf("")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -64,27 +67,24 @@ 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() }
setupPopularTokensRecyclerView()
btnTokensSaveChanges.setOnClickListener {
store.dispatch(TokensAction.SaveChanges(viewAdapter.getAddedItems()))
}
}
private fun setupPopularTokensRecyclerView() = with(binding) { cvCurrencies.setContent {
viewAdapter = CurrenciesAdapter() AppCompatTheme {
viewAdapter.setOnItemAddListener { CurrenciesScreen(
btnTokensSaveChanges.isEnabled = viewAdapter.getAddedItems().isNotEmpty() tokensState = tokensState,
searchInput = searchInput
) { tokens, blockchains ->
store.dispatch(TokensAction.SaveChanges(tokens, blockchains))
}
}
} }
rvPopularTokens.layoutManager = LinearLayoutManager(context)
rvPopularTokens.adapter = viewAdapter
} }
override fun newState(state: TokensState) { override fun newState(state: TokensState) {
if (activity == null || view == null) return if (activity == null || view == null) return
val toolbarTitle =
viewAdapter.addedCurrencies = state.addedCurrencies if (state.allowToAdd) R.string.add_tokens_title else R.string.search_tokens_title
viewAdapter.submitUnfilteredList(state.shownCurrencies) binding.toolbar.title = getString(toolbarTitle)
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -102,13 +102,13 @@ class AddTokensFragment : Fragment(R.layout.fragment_add_tokens),
searchView.queryHint = searchView.getString(R.string.add_token_search_hint) searchView.queryHint = searchView.getString(R.string.add_token_search_hint)
searchView.maxWidth = android.R.attr.width searchView.maxWidth = android.R.attr.width
searchView.inputtedTextAsFlow() searchView.inputtedTextAsFlow()
.debounce(400) .debounce(400)
.distinctUntilChanged() .distinctUntilChanged()
.onEach { .onEach {
viewAdapter.filter(searchView.query) searchInput.value = it.lowercase()
} }
.launchIn(mainScope) .launchIn(mainScope)
return super.onCreateOptionsMenu(menu, inflater); return super.onCreateOptionsMenu(menu, inflater)
} }
override fun onDestroy() { override fun onDestroy() {

View file

@ -1,254 +0,0 @@
package com.tangem.tap.features.tokens.ui.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.squareup.picasso.Picasso
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.common.extensions.VoidCallback
import com.tangem.tap.common.extensions.getString
import com.tangem.tap.common.extensions.hide
import com.tangem.tap.common.extensions.loadCurrenciesIcon
import com.tangem.tap.common.extensions.show
import com.tangem.tap.domain.tokens.CardCurrencies
import com.tangem.tap.domain.tokens.getTokensName
import com.tangem.tap.features.tokens.redux.CurrencyListItem
import com.tangem.tap.features.tokens.redux.TokensAction
import com.tangem.tap.store
import com.tangem.wallet.R
import com.tangem.wallet.databinding.ItemCurrencySubtitleBinding
import com.tangem.wallet.databinding.ItemPopularTokenBinding
import java.util.*
class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>(DiffUtilCallback) {
var addedCurrencies: CardCurrencies? = null
private var unfilteredList = listOf<CurrencyListItem>()
private val currentlyAddedItems = mutableListOf<CurrencyListItem>()
private var vhOnItemAddListener: ((CurrencyListItem) -> Unit) = {
currentlyAddedItems.add(it)
onItemAddListener?.invoke()
}
private var onItemAddListener: VoidCallback? = null
fun submitUnfilteredList(list: List<CurrencyListItem>) {
unfilteredList = list
submitList(list)
}
fun setOnItemAddListener(itemAddListener: VoidCallback) {
onItemAddListener = itemAddListener
if (currentlyAddedItems.isNotEmpty()) itemAddListener()
}
fun getAddedItems(): List<CurrencyListItem> {
return currentlyAddedItems.toList()
}
override fun getItemViewType(position: Int): Int {
return when (currentList[position]) {
is CurrencyListItem.TitleListItem -> 0
is CurrencyListItem.BlockchainListItem, is CurrencyListItem.TokenListItem -> 1
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
0 -> TitleViewHolder(
binding = ItemCurrencySubtitleBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
)
1 -> CurrenciesViewHolder(
binding = ItemPopularTokenBinding
.inflate(LayoutInflater.from(parent.context), parent, false),
onItemAddListener = vhOnItemAddListener
)
else -> CurrenciesViewHolder(
binding = ItemPopularTokenBinding
.inflate(LayoutInflater.from(parent.context), parent, false),
onItemAddListener = vhOnItemAddListener
)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val listItem = currentList[position]
if (holder is TitleViewHolder && listItem is CurrencyListItem.TitleListItem) {
holder.bind(listItem)
} else if (holder is CurrenciesViewHolder) {
holder.bind(listItem, addedCurrencies, currentlyAddedItems)
}
}
object DiffUtilCallback : DiffUtil.ItemCallback<CurrencyListItem>() {
override fun areContentsTheSame(
oldItem: CurrencyListItem, newItem: CurrencyListItem,
) = oldItem == newItem
override fun areItemsTheSame(
oldItem: CurrencyListItem, newItem: CurrencyListItem,
) = oldItem == newItem
}
fun filter(query: CharSequence?) {
val list = mutableListOf<CurrencyListItem>()
if (!query.isNullOrEmpty()) {
store.dispatch(TokensAction.OpenAllTokens)
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)
}
is CurrencyListItem.TokenListItem -> {
element.token.name.toLowerCase(Locale.US)
.contains(queryNormalized) ||
element.token.symbol.toLowerCase(Locale.US)
.contains(queryNormalized)
}
is CurrencyListItem.TitleListItem -> true
}
})
} else {
list.addAll(unfilteredList)
}
submitList(list)
}
class CurrenciesViewHolder(
private val binding: ItemPopularTokenBinding,
private val onItemAddListener: ((CurrencyListItem) -> Unit),
) : RecyclerView.ViewHolder(binding.root) {
fun bind(
currency: CurrencyListItem,
addedCurrencies: CardCurrencies?,
currentlyAddedItems: MutableList<CurrencyListItem>
) {
when (currency) {
is CurrencyListItem.BlockchainListItem -> {
val addedBlockchains = addedCurrencies?.blockchains ?: listOf()
val currentlyAdded =
currentlyAddedItems.filterIsInstance<CurrencyListItem.BlockchainListItem>()
bindBlockchain(currency, addedBlockchains, currentlyAdded)
}
is CurrencyListItem.TokenListItem -> {
val addedTokens = addedCurrencies?.tokens ?: listOf()
val currentlyAdded =
currentlyAddedItems.filterIsInstance<CurrencyListItem.TokenListItem>()
bindToken(currency, addedTokens, currentlyAdded)
}
}
}
private fun bindBlockchain(
currency: CurrencyListItem.BlockchainListItem,
addedBlockchains: List<Blockchain>,
currentlyAdded: List<CurrencyListItem.BlockchainListItem>
) = with(binding) {
val blockchain = currency.blockchain
Picasso.get().loadCurrenciesIcon(ivCurrency, tvTokenLetter, null, blockchain)
tvCurrencyName.text = blockchain.fullName
tvCurrencySymbol.text = blockchain.currency
btnAddToken.setOnClickListener {
onItemAddListener.invoke(currency)
currency.isAdded = true
modifyAddTokenButton(currency)
}
val isAddedBefore = addedBlockchains.contains(blockchain)
val isCurrentlyAdded = currentlyAdded.any { it.blockchain == blockchain }
currency.isAdded = isAddedBefore || isCurrentlyAdded
modifyAddTokenButton(currency)
}
private fun bindToken(
currency: CurrencyListItem.TokenListItem,
addedTokens: List<Token>,
currentlyAdded: List<CurrencyListItem.TokenListItem>
) = with(binding) {
val token = currency.token
Picasso.get()
.loadCurrenciesIcon(ivCurrency, tvTokenLetter, token, token.blockchain)
tvCurrencyName.text = token.name
tvCurrencySymbol.text = tvCurrencySymbol.getString(
R.string.token_symbol_address_format,
token.symbol, token.contractAddress
)
btnAddToken.setOnClickListener {
onItemAddListener.invoke(currency)
currency.isAdded = true
modifyAddTokenButton(currency)
}
val isAddedBefore = addedTokens.any { it == token }
val isCurrentlyAdded = currentlyAdded.any { it.token == token }
currency.isAdded = isAddedBefore || isCurrentlyAdded
modifyAddTokenButton(currency)
}
private fun modifyAddTokenButton(currency: CurrencyListItem) = with(binding) {
if (currency.isLocked) {
btnAddToken.setText(R.string.common_add)
btnAddToken.isEnabled = false
} else {
val text = if (currency.isAdded) R.string.add_token_added else R.string.common_add
btnAddToken.setText(text)
btnAddToken.isEnabled = !currency.isAdded
}
}
}
class TitleViewHolder(val binding: ItemCurrencySubtitleBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(title: CurrencyListItem.TitleListItem) = with(binding) {
if (title.blockchain != null) {
val subtitle = root.getString(title.titleResId, title.blockchain.getTokensName())
tvSubtitle.text = subtitle.uppercase()
clSubtitleContainer.setOnClickListener {
val rotation = if (title.isContentShown) -90f else 90f
store.dispatch(
TokensAction.ToggleShowTokensForBlockchain(
title.isContentShown, title.blockchain
)
)
ivToggleSublistVisibility.animate().rotation(rotation).withEndAction {
showArrow(title.isContentShown)
}
}
showArrow(title.isContentShown)
} else {
tvSubtitle.text = root.getString(title.titleResId).uppercase()
ivToggleSublistVisibility.hide()
}
}
private fun showArrow(isContentShown: Boolean) = with(binding) {
ivToggleSublistVisibility.show()
val drawable = if (isContentShown) {
R.drawable.ic_arrow_angle_down
} else {
R.drawable.ic_arrow_angle_right
}
ivToggleSublistVisibility.setImageResource(drawable)
ivToggleSublistVisibility.rotation = 0f
}
}
}

View file

@ -0,0 +1,108 @@
package com.tangem.tap.features.tokens.ui.compose
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.SubcomposeAsyncImage
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.tap.common.extensions.getGreyedOutIconRes
import com.tangem.tap.common.extensions.getRoundIconRes
import com.tangem.tap.domain.tokens.Currency
import com.tangem.tap.domain.tokens.fromNetworkId
import com.tangem.wallet.R
@Composable
fun CollapsedCurrencyItem(
currency: Currency,
addedTokens: List<Token>,
addedBlockchains: List<Blockchain>,
onCurrencyClick: (String) -> Unit
) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = { onCurrencyClick(currency.id) })
) {
val blockchain = Blockchain.fromNetworkId(currency.id)
val iconRes = if (blockchain == Blockchain.Unknown) {
currency.iconUrl
} else {
blockchain.getRoundIconRes()
}
SubcomposeAsyncImage(
model = iconRes,
contentDescription = currency.id,
loading = { CurrencyPlaceholderIcon(currency.id) },
error = { CurrencyPlaceholderIcon(currency.id) },
modifier = Modifier
.clip(CircleShape)
.padding(16.dp)
.size(46.dp),
)
Column(
modifier = Modifier
.fillMaxHeight()
.weight(1f)
.align(Alignment.CenterVertically)
) {
Text(
text = currency.name,
fontSize = 17.sp,
fontWeight = FontWeight.Normal,
color = Color(0xFF1C1C1E),
)
Spacer(modifier = Modifier.size(6.dp))
Row {
if (currency.contracts != null) {
currency.contracts.map { contract ->
val added =
addedTokens.map { it.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))
}
} else {
val added = addedBlockchains.contains(blockchain)
val icon =
if (added) blockchain.getRoundIconRes() else blockchain.getGreyedOutIconRes()
Image(
painter = painterResource(id = icon),
contentDescription = null,
Modifier
.size(20.dp)
)
}
}
}
Image(
painter = painterResource(id = R.drawable.ic_arrow_collapsed),
contentDescription = null,
Modifier
.padding(20.dp)
.align(Alignment.CenterVertically)
)
}
}

View file

@ -0,0 +1,101 @@
package com.tangem.tap.features.tokens.ui.compose
import androidx.compose.foundation.layout.padding
import androidx.compose.material.ExtendedFloatingActionButton
import androidx.compose.material.FabPosition
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.tap.common.compose.Keyboard
import com.tangem.tap.common.compose.keyboardAsState
import com.tangem.tap.common.extensions.pixelsToDp
import com.tangem.tap.domain.tokens.Currency
import com.tangem.tap.domain.tokens.fromNetworkId
import com.tangem.tap.features.tokens.redux.TokensState
import com.tangem.tap.store
import com.tangem.wallet.R
@Composable
fun CurrenciesScreen(
tokensState: MutableState<TokensState> = mutableStateOf(store.state.tokensState),
searchInput: MutableState<String>,
onSaveChanges: (List<Token>, List<Blockchain>) -> Unit
) {
val addedTokensState = remember { mutableStateOf(tokensState.value.addedTokens) }
val addedBlockchainsState = remember { mutableStateOf(tokensState.value.addedBlockchains) }
val isKeyboardOpen by keyboardAsState()
val onAddCurrencyToggleClick = { currency: Currency, contract: Token? ->
if (contract != null) {
val mutableList = addedTokensState.value.toMutableList()
if (mutableList.contains(contract)) {
mutableList.remove(contract)
} else {
mutableList.add(contract)
}
addedTokensState.value = mutableList
} else {
val blockchain = Blockchain.fromNetworkId(currency.id)
val mutableList = addedBlockchainsState.value.toMutableList()
if (mutableList.contains(blockchain)) {
mutableList.remove(blockchain)
} else {
mutableList.add(blockchain)
}
addedBlockchainsState.value = mutableList
}
}
Scaffold(
// topBar =,
floatingActionButton = {
if (tokensState.value.allowToAdd) SaveChangesButton(isKeyboardOpen) {
onSaveChanges(addedTokensState.value, addedBlockchainsState.value)
}
},
floatingActionButtonPosition = FabPosition.Center,
) {
ListOfCurrencies(
currencies = tokensState.value.currencies,
nonRemovableTokens = tokensState.value.nonRemovableTokens,
nonRemovableBlockchains = tokensState.value.nonRemovableBlockchains,
addedTokens = addedTokensState.value,
addedBlockchains = addedBlockchainsState.value,
searchInput = searchInput.value,
allowToAdd = tokensState.value.allowToAdd,
onAddCurrencyToggled = onAddCurrencyToggleClick
)
}
}
@Composable
fun SaveChangesButton(keyboardState: Keyboard, onSaveChanges: () -> Unit) {
val padding = if (keyboardState is Keyboard.Opened) {
LocalContext.current.pixelsToDp(keyboardState.height)
} else {
0
}
ExtendedFloatingActionButton(
text = {
Text(
text = stringResource(id = R.string.common_save_changes),
)
},
onClick = onSaveChanges,
backgroundColor = Color(0xFF1ACE80),
contentColor = Color.White,
modifier = Modifier.padding(bottom = padding.dp)
)
}

View file

@ -0,0 +1,37 @@
package com.tangem.tap.features.tokens.ui.compose
import androidx.compose.runtime.Composable
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.tap.domain.tokens.Currency
import com.tangem.tap.features.tokens.redux.ContractAddress
@Composable
fun CurrencyItem(
currency: Currency,
nonRemovableTokens: List<ContractAddress>,
nonRemovableBlockchains: List<Blockchain>,
addedTokens: List<Token>,
addedBlockchains: List<Blockchain>,
allowToAdd: Boolean,
expanded: Boolean,
onCurrencyClick: (String) -> Unit,
onAddCurrencyToggled: (Currency, Token?) -> Unit
) {
if (expanded) {
ExpandedCurrencyItem(
currency = currency,
nonRemovableTokens = nonRemovableTokens,
nonRemovableBlockchains = nonRemovableBlockchains,
addedTokens = addedTokens,
addedBlockchains = addedBlockchains,
allowToAdd = allowToAdd,
onCurrencyClick = onCurrencyClick, onAddCurrencyToggled = onAddCurrencyToggled
)
} else {
CollapsedCurrencyItem(
currency = currency, addedTokens = addedTokens,
addedBlockchains = addedBlockchains, onCurrencyClick
)
}
}

View file

@ -0,0 +1,38 @@
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.CircleShape
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.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@Composable
fun CurrencyPlaceholderIcon(id: String) {
val letterColor: Color = Color.White
val circleColor: Color = Color.Black
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.background(circleColor, shape = CircleShape)
)
{
Text(
text = id.firstOrNull()?.titlecase() ?: "",
textAlign = TextAlign.Center,
color = letterColor,
modifier = Modifier.padding(4.dp),
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
)
}
}

View file

@ -0,0 +1,155 @@
package com.tangem.tap.features.tokens.ui.compose
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Divider
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.SubcomposeAsyncImage
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.tap.common.extensions.getRoundIconRes
import com.tangem.tap.domain.tokens.Currency
import com.tangem.tap.domain.tokens.fromNetworkId
import com.tangem.tap.features.tokens.redux.ContractAddress
import com.tangem.wallet.R
@Composable
fun ExpandedCurrencyItem(
currency: Currency,
nonRemovableTokens: List<ContractAddress>,
nonRemovableBlockchains: List<Blockchain>,
addedTokens: List<Token>,
addedBlockchains: List<Blockchain>,
allowToAdd: Boolean,
onCurrencyClick: (String) -> Unit,
onAddCurrencyToggled: (Currency, Token?) -> Unit
) {
val blockchain = Blockchain.fromNetworkId(currency.id)
val iconRes = if (blockchain == Blockchain.Unknown) {
currency.iconUrl
} else {
blockchain.getRoundIconRes()
}
Column {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = { onCurrencyClick(currency.id) })
) {
SubcomposeAsyncImage(
model = iconRes,
contentDescription = currency.id,
loading = { CurrencyPlaceholderIcon(currency.id) },
error = { CurrencyPlaceholderIcon(currency.id) },
modifier = Modifier
.clip(CircleShape)
.padding(start = 16.dp, top = 16.dp, end = 16.dp)
.size(46.dp),
)
Column(
modifier = Modifier
.fillMaxHeight()
.weight(1f)
.padding(top = 14.dp)
.align(Alignment.CenterVertically)
) {
Text(
text = currency.name,
fontSize = 17.sp,
fontWeight = FontWeight.Normal,
color = Color(0xFF1C1C1E),
)
Spacer(modifier = Modifier.size(6.dp))
Text(
text = stringResource(id = R.string.currency_subtitle_expanded),
fontSize = 13.sp,
fontWeight = FontWeight.Normal,
color = Color(0xFF8E8E93),
)
}
Image(
painter = painterResource(id = R.drawable.ic_arrow_extended),
contentDescription = null,
Modifier
.padding(20.dp)
.align(Alignment.CenterVertically)
)
}
val blockchains = currency.contracts?.map { it.blockchain } ?: listOf(
Blockchain.fromNetworkId(currency.id)
)
Row {
Box(
modifier = Modifier
.fillMaxHeight()
) {
if (blockchains.size > 1) {
Divider(
color = Color(0xFFDEDEDE),
modifier = Modifier
.height((43 * blockchains.size - 1).dp)
.padding(start = 37.dp, top = 16.dp)
.width(1.dp)
)
}
Column {
blockchains.map {
Image(
painter = painterResource(id = R.drawable.ic_link),
contentDescription = null,
Modifier
.padding(
start = 37.dp,
)
)
Spacer(modifier = Modifier.size(13.5.dp))
}
}
}
Column(
modifier = Modifier
.fillMaxWidth()
.padding(top = 6.dp),
) {
blockchains.map { blockchain ->
val contract = currency.contracts?.firstOrNull { it.blockchain == blockchain }
val added = if (contract != null) {
addedTokens.map { it.contractAddress }.contains(contract.address)
} else {
addedBlockchains.contains(blockchain)
}
val canBeRemoved = if (contract != null) {
!nonRemovableTokens.contains(contract.address)
} else {
!nonRemovableBlockchains.contains(blockchain)
}
NetworkItem(
currency = currency,
contract = contract,
blockchain = blockchain, allowToAdd = allowToAdd,
added = added,
canBeRemoved = canBeRemoved,
onAddCurrencyToggled = onAddCurrencyToggled
)
}
}
}
}
}

View file

@ -0,0 +1,67 @@
package com.tangem.tap.features.tokens.ui.compose
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.tap.domain.tokens.Currency
import com.tangem.tap.features.tokens.redux.ContractAddress
@Composable
fun ListOfCurrencies(
currencies: List<Currency>,
nonRemovableTokens: List<ContractAddress>,
nonRemovableBlockchains: List<Blockchain>,
addedTokens: List<Token>,
addedBlockchains: List<Blockchain>,
searchInput: String,
allowToAdd: Boolean,
onAddCurrencyToggled: (Currency, Token?) -> Unit
) {
val expandedCurrencies = remember { mutableStateOf(listOf("")) }
val onCurrencyClick = { currencyId: String ->
val mutableList = expandedCurrencies.value.toMutableList()
if (mutableList.contains(currencyId)) {
mutableList.remove(currencyId)
} else {
mutableList.add(currencyId)
}
expandedCurrencies.value = mutableList
}
LazyColumn(
modifier = Modifier.fillMaxSize(),
) {
val filteredCurrencies = if (searchInput.isBlank()) {
currencies
} else {
currencies.asSequence().filter {
it.name.lowercase().contains(searchInput) || it.symbol.lowercase()
.contains(searchInput)
}.toList()
}
items(filteredCurrencies) { currency ->
CurrencyItem(
currency = currency,
nonRemovableTokens = nonRemovableTokens,
nonRemovableBlockchains = nonRemovableBlockchains,
addedTokens = addedTokens,
addedBlockchains = addedBlockchains,
allowToAdd = allowToAdd,
expanded = expandedCurrencies.value.contains(currency.id),
onCurrencyClick = onCurrencyClick,
onAddCurrencyToggled = onAddCurrencyToggled
)
}
}
}

View file

@ -0,0 +1,85 @@
package com.tangem.tap.features.tokens.ui.compose
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Switch
import androidx.compose.material.SwitchDefaults
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.SubcomposeAsyncImage
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.tap.common.extensions.getGreyedOutIconRes
import com.tangem.tap.common.extensions.getNetworkName
import com.tangem.tap.common.extensions.getRoundIconRes
import com.tangem.tap.domain.tokens.Contract
import com.tangem.tap.domain.tokens.Currency
@Composable
fun NetworkItem(
currency: Currency, contract: Contract?,
blockchain: Blockchain, allowToAdd: Boolean,
added: Boolean, canBeRemoved: Boolean,
onAddCurrencyToggled: (Currency, Token?) -> Unit
) {
Row(
modifier = Modifier
.fillMaxWidth()
) {
SubcomposeAsyncImage(
model = if (added) blockchain.getRoundIconRes() else blockchain.getGreyedOutIconRes(),
contentDescription = blockchain.fullName,
loading = { CurrencyPlaceholderIcon(blockchain.id) },
error = { CurrencyPlaceholderIcon(blockchain.id) },
modifier = Modifier
.clip(CircleShape)
.padding(start = 8.dp, top = 16.dp, bottom = 16.dp, end = 6.dp)
.size(20.dp)
.align(Alignment.CenterVertically)
)
Row(modifier = Modifier
.fillMaxHeight()
.weight(1f)
.align(Alignment.CenterVertically)) {
Text(
text = blockchain.name.uppercase(),
fontSize = 13.sp,
fontWeight = FontWeight.SemiBold,
color = if (added) Color.Black else Color(0xFF848488),
)
Spacer(modifier = Modifier.size(3.dp))
Text(
text = if (contract != null) blockchain.getNetworkName().uppercase() else "MAIN",
fontSize = 13.sp,
fontWeight = FontWeight.Normal,
color = if (contract != null) Color(0xFF8E8E93) else Color(0xFF1ACE80),
)
}
val token = if (contract != null) {
Token(
name = currency.name, symbol = currency.symbol, contractAddress = contract.address,
decimals = contract.decimalCount, blockchain = contract.blockchain
)
} else {
null
}
if (allowToAdd) Switch(
checked = added,
enabled = canBeRemoved,
onCheckedChange = { onAddCurrencyToggled(currency, token) },
modifier = Modifier.padding(start = 16.dp, end = 16.dp),
colors = SwitchDefaults.colors(
checkedThumbColor = Color(0xFF1ACE80)
)
)
}
}

View file

@ -98,7 +98,11 @@ class MultiWalletView : WalletView {
binding.btnAddToken.setOnClickListener { binding.btnAddToken.setOnClickListener {
store.dispatch(TokensAction.LoadCurrencies) store.dispatch(TokensAction.LoadCurrencies)
store.dispatch(TokensAction.AllowToAddTokens(true))
store.dispatch(TokensAction.SetAddedCurrencies(state.wallets)) store.dispatch(TokensAction.SetAddedCurrencies(state.wallets))
store.dispatch(TokensAction.SetNonRemovableCurrencies(
state.wallets.filterNot { state.canBeRemoved(it) })
)
store.dispatch(NavigationAction.NavigateTo(AppScreen.AddTokens)) store.dispatch(NavigationAction.NavigateTo(AppScreen.AddTokens))
} }
handleErrorStates(state = state, binding = binding, fragment = fragment) handleErrorStates(state = state, binding = binding, fragment = fragment)

View file

@ -23,7 +23,9 @@ class OnramperService(
) : ExchangeService, ExchangeUrlBuilder { ) : ExchangeService, ExchangeUrlBuilder {
private val api: OnramperApi by lazy { private val api: OnramperApi by lazy {
createRetrofitInstance(OnramperApi.BASE_URL, listOf(AddKeyToHeaderInterceptor(apiKey))) createRetrofitInstance(OnramperApi.BASE_URL,
listOf(AddKeyToHeaderInterceptor(apiKey))
)
.create(OnramperApi::class.java) .create(OnramperApi::class.java)
} }

View file

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="10dp"
android:viewportHeight="10" android:viewportWidth="17"
android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#CCCCCC" android:fillType="evenOdd" android:pathData="M0.2689,0.95C0.6458,0.5463 1.2786,0.5244 1.6823,0.9013L8.5,7.2644L15.3177,0.9013C15.7214,0.5244 16.3542,0.5463 16.7311,0.95C17.1079,1.3538 17.0861,1.9865 16.6823,2.3634L8.5,10.0002L0.3177,2.3634C-0.0861,1.9865 -0.1079,1.3538 0.2689,0.95Z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="10dp"
android:viewportHeight="10" android:viewportWidth="17"
android:width="17dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#CCCCCC" android:fillType="evenOdd" android:pathData="M0.2689,9.6823C0.6458,10.0861 1.2786,10.1079 1.6823,9.731L8.5,3.3679L15.3177,9.731C15.7214,10.1079 16.3542,10.0861 16.7311,9.6823C17.1079,9.2786 17.0861,8.6458 16.6823,8.2689L8.5,0.6321L0.3177,8.2689C-0.0861,8.6458 -0.1079,9.2786 0.2689,9.6823Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#A1A1A4" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#F1F1F1" android:fillType="evenOdd" android:pathData="M16,8C16,12.4183 12.4183,16 8,16C3.5817,16 0,12.4183 0,8C0,3.5817 3.5817,0 8,0C12.4183,0 16,3.5817 16,8ZM5.733,11.1836H4.1804C3.8542,11.1836 3.6931,11.1836 3.5948,11.1207C3.4887,11.0519 3.4238,10.9379 3.416,10.8121C3.4101,10.6962 3.4906,10.5547 3.6518,10.2717L7.4853,3.5146C7.6484,3.2277 7.7309,3.0842 7.8351,3.0312C7.9471,2.9742 8.0808,2.9742 8.1928,3.0312C8.297,3.0842 8.3795,3.2277 8.5426,3.5146L9.3307,4.8903L9.3347,4.8973C9.5109,5.2052 9.6002,5.3613 9.6392,5.5251C9.6825,5.7039 9.6825,5.8926 9.6392,6.0715C9.5999,6.2365 9.5115,6.3938 9.3327,6.7063L7.319,10.2658L7.3138,10.2749C7.1365,10.5853 7.0466,10.7426 6.922,10.8613C6.7864,10.991 6.6233,11.0853 6.4445,11.1384C6.2813,11.1836 6.0986,11.1836 5.733,11.1836ZM9.6538,11.1836H11.8785C12.2067,11.1836 12.3718,11.1836 12.4701,11.1188C12.5762,11.05 12.643,10.934 12.6489,10.8083C12.6546,10.6961 12.5758,10.5601 12.4213,10.2935C12.416,10.2845 12.4107,10.2752 12.4052,10.2658L11.2909,8.3595L11.2782,8.3381C11.1216,8.0733 11.0426,7.9395 10.941,7.8878C10.8291,7.8309 10.6973,7.8309 10.5853,7.8878C10.4831,7.9409 10.4006,8.0805 10.2375,8.3615L9.1271,10.2678L9.1233,10.2744C8.9607,10.555 8.8795,10.6952 8.8854,10.8102C8.8932,10.936 8.9581,11.0519 9.0642,11.1207C9.1605,11.1836 9.3256,11.1836 9.6538,11.1836Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#ffffff" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#E74142" android:fillType="evenOdd" android:pathData="M16,8C16,12.4183 12.4183,16 8,16C3.5817,16 0,12.4183 0,8C0,3.5817 3.5817,0 8,0C12.4183,0 16,3.5817 16,8ZM5.733,11.1836H4.1804C3.8542,11.1836 3.6931,11.1836 3.5948,11.1207C3.4887,11.0519 3.4238,10.9379 3.416,10.8121C3.4101,10.6962 3.4906,10.5547 3.6518,10.2717L7.4853,3.5146C7.6484,3.2277 7.7309,3.0842 7.8351,3.0312C7.9471,2.9742 8.0808,2.9742 8.1928,3.0312C8.297,3.0842 8.3795,3.2277 8.5426,3.5146L9.3307,4.8903L9.3347,4.8973C9.5109,5.2052 9.6002,5.3613 9.6392,5.5251C9.6825,5.7039 9.6825,5.8926 9.6392,6.0715C9.5999,6.2365 9.5115,6.3938 9.3327,6.7063L7.319,10.2658L7.3138,10.2749C7.1365,10.5853 7.0466,10.7426 6.922,10.8613C6.7864,10.991 6.6233,11.0853 6.4445,11.1384C6.2813,11.1836 6.0986,11.1836 5.733,11.1836ZM9.6538,11.1836H11.8785C12.2067,11.1836 12.3718,11.1836 12.4701,11.1188C12.5762,11.05 12.643,10.934 12.6489,10.8083C12.6546,10.6961 12.5758,10.5601 12.4213,10.2935C12.416,10.2845 12.4107,10.2752 12.4052,10.2658L11.2909,8.3595L11.2782,8.3381C11.1216,8.0733 11.0426,7.9395 10.941,7.8878C10.8291,7.8309 10.6973,7.8309 10.5853,7.8878C10.4831,7.9409 10.4006,8.0805 10.2375,8.3615L9.1271,10.2678L9.1233,10.2744C8.9607,10.555 8.8795,10.6952 8.8854,10.8102C8.8932,10.936 8.9581,11.0519 9.0642,11.1207C9.1605,11.1836 9.3256,11.1836 9.6538,11.1836Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:pathData="M8,0L8,0A8,8 0,0 1,16 8L16,8A8,8 0,0 1,8 16L8,16A8,8 0,0 1,0 8L0,8A8,8 0,0 1,8 0z"/>
<path android:fillColor="#A1A1A4" android:fillType="evenOdd" android:pathData="M6.0578,7.202L8.0002,5.2604L9.9434,7.2036L11.073,6.0733L8.0002,2.9998L4.9275,6.0725L6.0578,7.202ZM2.999,8.0005L4.129,6.8706L5.259,8.0005L4.129,9.1304L2.999,8.0005ZM8.0002,10.7408L6.0578,8.7985L4.9258,9.9272L4.9274,9.9288L8.0002,13.0007L11.073,9.9272L11.0738,9.9264L9.9434,8.7977L8.0002,10.7408ZM10.74,8.0009L11.87,6.871L12.9999,8.0009L11.87,9.1308L10.74,8.0009ZM8.0004,6.8526L9.1466,7.9995H9.1473L9.1466,8.0003L8.0004,9.1472L6.8542,8.0019L6.8526,7.9995L6.8542,7.9979L7.0549,7.7973L7.1528,7.7001L8.0004,6.8526Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F3BA2F" android:pathData="M8,0L8,0A8,8 0,0 1,16 8L16,8A8,8 0,0 1,8 16L8,16A8,8 0,0 1,0 8L0,8A8,8 0,0 1,8 0z"/>
<path android:fillColor="#ffffff" android:fillType="evenOdd" android:pathData="M6.0578,7.202L8.0002,5.2604L9.9434,7.2036L11.073,6.0733L8.0002,2.9998L4.9275,6.0725L6.0578,7.202ZM2.999,8.0005L4.129,6.8706L5.259,8.0005L4.129,9.1304L2.999,8.0005ZM8.0002,10.7408L6.0578,8.7985L4.9258,9.9272L4.9274,9.9288L8.0002,13.0007L11.073,9.9272L11.0738,9.9264L9.9434,8.7977L8.0002,10.7408ZM10.74,8.0009L11.87,6.871L12.9999,8.0009L11.87,9.1308L10.74,8.0009ZM8.0004,6.8526L9.1466,7.9995H9.1473L9.1466,8.0003L8.0004,9.1472L6.8542,8.0019L6.8526,7.9995L6.8542,7.9979L7.0549,7.7973L7.1528,7.7001L8.0004,6.8526Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:pathData="M8,16C12.4183,16 16,12.4183 16,8C16,3.5817 12.4183,0 8,0C3.5817,0 0,3.5817 0,8C0,12.4183 3.5817,16 8,16Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M10.6797,5.3445C10.272,4.4259 9.3351,4.2295 8.1882,4.4198L7.8196,3L6.9507,3.223L7.3131,4.6387C7.0845,4.696 6.8498,4.7451 6.6171,4.8106L6.2547,3.403L5.3858,3.626L5.7543,5.0458C5.567,5.099 4,5.498 4,5.498L4.2389,6.4227C4.2389,6.4227 4.8772,6.2447 4.871,6.259C5.2252,6.1669 5.3919,6.3429 5.4702,6.5086L6.4833,10.3998C6.4956,10.5123 6.475,10.7046 6.232,10.77C6.2465,10.7782 5.5999,10.9317 5.5999,10.9317L5.6946,12.0098C5.6946,12.0098 7.2472,11.615 7.451,11.5638L7.8237,13L8.6927,12.777L8.32,11.3306C8.5588,11.2754 8.7915,11.2181 9.018,11.1588L9.3886,12.597L10.2576,12.374L9.8849,10.9399C11.2233,10.6166 12.1684,9.7778 11.9748,8.4951C11.8513,7.7218 11.0009,7.0876 10.2946,7.016C10.7291,6.6334 10.9494,6.0749 10.6797,5.3445ZM10.2617,8.7304C10.4346,10.0008 8.6577,10.1563 8.0708,10.3097L7.5602,8.4092C8.1491,8.2557 9.9693,7.6113 10.2617,8.7304ZM9.191,6.1424C9.3742,7.2717 7.8546,7.4026 7.3646,7.5274L6.8992,5.8028C7.3913,5.6821 8.8183,5.097 9.191,6.1424Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#0AC18E" android:pathData="M8,16C12.4183,16 16,12.4183 16,8C16,3.5817 12.4183,0 8,0C3.5817,0 0,3.5817 0,8C0,12.4183 3.5817,16 8,16Z"/>
<path android:fillColor="#ffffff" android:pathData="M10.6797,5.3445C10.272,4.4259 9.3351,4.2295 8.1882,4.4198L7.8196,3L6.9507,3.223L7.3131,4.6387C7.0845,4.696 6.8498,4.7451 6.6171,4.8106L6.2547,3.403L5.3858,3.626L5.7543,5.0458C5.567,5.099 4,5.498 4,5.498L4.2389,6.4227C4.2389,6.4227 4.8772,6.2447 4.871,6.259C5.2252,6.1669 5.3919,6.3429 5.4702,6.5086L6.4833,10.3998C6.4956,10.5123 6.475,10.7046 6.232,10.77C6.2465,10.7782 5.5999,10.9317 5.5999,10.9317L5.6946,12.0098C5.6946,12.0098 7.2472,11.615 7.451,11.5638L7.8237,13L8.6927,12.777L8.32,11.3306C8.5588,11.2754 8.7915,11.2181 9.018,11.1588L9.3886,12.597L10.2576,12.374L9.8849,10.9399C11.2233,10.6166 12.1684,9.7778 11.9748,8.4951C11.8513,7.7218 11.0009,7.0876 10.2946,7.016C10.7291,6.6334 10.9494,6.0749 10.6797,5.3445ZM10.2617,8.7304C10.4346,10.0008 8.6577,10.1563 8.0708,10.3097L7.5602,8.4092C8.1491,8.2557 9.9693,7.6113 10.2617,8.7304ZM9.191,6.1424C9.3742,7.2717 7.8546,7.4026 7.3646,7.5274L6.8992,5.8028C7.3913,5.6821 8.8183,5.097 9.191,6.1424Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:pathData="M15.7605,9.9353C14.6919,14.221 10.3507,16.8292 6.064,15.7605C1.7791,14.692 -0.8295,10.351 0.2396,6.0656C1.3077,1.7794 5.649,-0.8291 9.9344,0.2394C14.2209,1.3079 16.8292,5.6493 15.7605,9.9353Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M11.5275,6.8603C11.6868,5.7958 10.8762,5.2236 9.7678,4.8418L10.1273,3.3998L9.2495,3.1811L8.8995,4.5851C8.6687,4.5276 8.4317,4.4733 8.1961,4.4196L8.5487,3.0064L7.6713,2.7876L7.3116,4.2291C7.1205,4.1856 6.933,4.1426 6.751,4.0973L6.752,4.0928L5.5414,3.7906L5.3078,4.7281C5.3078,4.7281 5.9592,4.8773 5.9454,4.8866C6.301,4.9753 6.3652,5.2106 6.3545,5.3971L5.9449,7.0398C5.9694,7.0461 6.0012,7.0551 6.0362,7.0691C6.0069,7.0618 5.9757,7.0538 5.9434,7.0461L5.3693,9.3473C5.3258,9.4553 5.2156,9.6173 4.9671,9.5558C4.9758,9.5685 4.329,9.3965 4.329,9.3965L3.8932,10.4013L5.0356,10.686C5.2481,10.7393 5.4563,10.795 5.6614,10.8475L5.2981,12.306L6.1749,12.5248L6.5347,11.0818C6.7742,11.1468 7.0068,11.2068 7.2343,11.2633L6.8758,12.6995L7.7536,12.9182L8.1169,11.4625C9.6138,11.7458 10.7394,11.6315 11.2132,10.2778C11.595,9.1878 11.1942,8.559 10.4066,8.149C10.9802,8.0168 11.4122,7.6396 11.5275,6.8603ZM9.5218,9.6725C9.2505,10.7625 7.4151,10.1733 6.82,10.0255L7.3021,8.0933C7.8971,8.2418 9.8053,8.5358 9.5218,9.6725ZM9.7933,6.8446C9.5458,7.8361 8.0181,7.3323 7.5226,7.2088L7.9596,5.4563C8.4552,5.5798 10.0511,5.8103 9.7933,6.8446Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F7931A" android:pathData="M15.7605,9.9353C14.6919,14.221 10.3507,16.8292 6.064,15.7605C1.7791,14.692 -0.8295,10.351 0.2396,6.0656C1.3077,1.7794 5.649,-0.8291 9.9344,0.2394C14.2209,1.3079 16.8292,5.6493 15.7605,9.9353Z"/>
<path android:fillColor="#ffffff" android:pathData="M11.5275,6.8603C11.6868,5.7958 10.8762,5.2236 9.7678,4.8418L10.1273,3.3998L9.2495,3.1811L8.8995,4.5851C8.6687,4.5276 8.4317,4.4733 8.1961,4.4196L8.5487,3.0064L7.6713,2.7876L7.3116,4.2291C7.1205,4.1856 6.933,4.1426 6.751,4.0973L6.752,4.0928L5.5414,3.7906L5.3078,4.7281C5.3078,4.7281 5.9592,4.8773 5.9454,4.8866C6.301,4.9753 6.3652,5.2106 6.3545,5.3971L5.9449,7.0398C5.9694,7.0461 6.0012,7.0551 6.0362,7.0691C6.0069,7.0618 5.9757,7.0538 5.9434,7.0461L5.3693,9.3473C5.3258,9.4553 5.2156,9.6173 4.9671,9.5558C4.9758,9.5685 4.329,9.3965 4.329,9.3965L3.8932,10.4013L5.0356,10.686C5.2481,10.7393 5.4563,10.795 5.6614,10.8475L5.2981,12.306L6.1749,12.5248L6.5347,11.0818C6.7742,11.1468 7.0068,11.2068 7.2343,11.2633L6.8758,12.6995L7.7536,12.9182L8.1169,11.4625C9.6138,11.7458 10.7394,11.6315 11.2132,10.2778C11.595,9.1878 11.1942,8.559 10.4066,8.149C10.9802,8.0168 11.4122,7.6396 11.5275,6.8603ZM9.5218,9.6725C9.2505,10.7625 7.4151,10.1733 6.82,10.0255L7.3021,8.0933C7.8971,8.2418 9.8053,8.5358 9.5218,9.6725ZM9.7933,6.8446C9.5458,7.8361 8.0181,7.3323 7.5226,7.2088L7.9596,5.4563C8.4552,5.5798 10.0511,5.8103 9.7933,6.8446Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:fillType="evenOdd" android:pathData="M8,0C12.4186,0 16,3.5814 16,8C16,12.4186 12.4186,16 8,16C3.5814,16 0,12.4186 0,8C0,3.5814 3.5814,0 8,0Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M4.3968,8.0001L4.4025,10.1154L6.2,11.1731V12.4116L3.3506,10.7404V7.3815L4.3968,8.0001ZM4.3968,5.8847V7.1174L3.35,6.4981V5.2655L4.3968,4.6462L5.4487,5.2655L4.3968,5.8847ZM6.9506,5.2655L7.9974,4.6462L9.0493,5.2655L7.9974,5.8847L6.9506,5.2655Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M5.1532,9.677V8.4385L6.2,9.0577V10.2904L5.1532,9.677ZM6.9506,11.6167L7.9974,12.2359L9.0493,11.6167V12.8494L7.9974,13.4686L6.9506,12.8494V11.6167ZM10.5505,5.2655L11.5973,4.6462L12.6492,5.2655V6.4981L11.5973,7.1174V5.8847L10.5505,5.2655ZM11.5973,10.1154L11.6031,8.0001L12.6499,7.3808V10.7398L9.8006,12.4109V11.1725L11.5973,10.1154Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M10.8468,9.6769L9.8,10.2903V9.0577L10.8468,8.4385V9.6769Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M10.8468,6.3232L10.8526,7.5616L9.05,8.6193V10.7398L8.0032,11.3533L6.9564,10.7398V8.6193L5.1538,7.5616V6.3232L6.2051,5.7039L7.9968,6.7667L9.7993,5.7039L10.8513,6.3232H10.8468ZM5.1532,4.2084L7.9974,2.5315L10.8468,4.2084L9.8,4.8276L7.9974,3.7648L6.2,4.8276L5.1532,4.2084Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#000000" android:fillType="evenOdd" android:pathData="M8,0C12.4186,0 16,3.5814 16,8C16,12.4186 12.4186,16 8,16C3.5814,16 0,12.4186 0,8C0,3.5814 3.5814,0 8,0Z"/>
<path android:fillColor="#F0B90B" android:pathData="M4.3968,8.0001L4.4025,10.1154L6.2,11.1731V12.4116L3.3506,10.7404V7.3815L4.3968,8.0001ZM4.3968,5.8847V7.1174L3.35,6.4981V5.2655L4.3968,4.6462L5.4487,5.2655L4.3968,5.8847ZM6.9506,5.2655L7.9974,4.6462L9.0493,5.2655L7.9974,5.8847L6.9506,5.2655Z"/>
<path android:fillColor="#F0B90B" android:pathData="M5.1532,9.677V8.4385L6.2,9.0577V10.2904L5.1532,9.677ZM6.9506,11.6167L7.9974,12.2359L9.0493,11.6167V12.8494L7.9974,13.4686L6.9506,12.8494V11.6167ZM10.5505,5.2655L11.5973,4.6462L12.6492,5.2655V6.4981L11.5973,7.1174V5.8847L10.5505,5.2655ZM11.5973,10.1154L11.6031,8.0001L12.6499,7.3808V10.7398L9.8006,12.4109V11.1725L11.5973,10.1154Z"/>
<path android:fillColor="#F0B90B" android:pathData="M10.8468,9.6769L9.8,10.2903V9.0577L10.8468,8.4385V9.6769Z"/>
<path android:fillColor="#F0B90B" android:pathData="M10.8468,6.3232L10.8526,7.5616L9.05,8.6193V10.7398L8.0032,11.3533L6.9564,10.7398V8.6193L5.1538,7.5616V6.3232L6.2051,5.7039L7.9968,6.7667L9.7993,5.7039L10.8513,6.3232H10.8468ZM5.1532,4.2084L7.9974,2.5315L10.8468,4.2084L9.8,4.8276L7.9974,3.7648L6.2,4.8276L5.1532,4.2084Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#A1A1A4" android:pathData="M7.8738,3.2662C8.098,3.1493 8.3717,3.4204 8.2526,3.6444C8.1834,3.827 7.9211,3.8755 7.7871,3.7364C7.6452,3.6028 7.6915,3.3388 7.8738,3.2662ZM5.4626,3.5261C5.5988,3.47 5.7712,3.5948 5.7573,3.7432C5.7718,3.9043 5.5747,4.0229 5.4359,3.9464C5.252,3.8751 5.273,3.5766 5.4626,3.5261ZM10.4011,3.9509C10.1883,3.9252 10.1546,3.5906 10.3595,3.5232C10.5184,3.4457 10.6642,3.591 10.6875,3.7417C10.6541,3.8703 10.5465,3.9881 10.4011,3.9509ZM6.0113,4.5523C6.2389,4.4083 6.5638,4.6228 6.5288,4.8872C6.517,5.1543 6.1623,5.309 5.9622,5.1284C5.7687,4.9867 5.798,4.6614 6.0113,4.5523ZM9.4869,4.7051C9.5884,4.4434 10,4.4354 10.1156,4.6903C10.2299,4.8886 10.0894,5.1342 9.8857,5.2016C9.616,5.2519 9.3599,4.9604 9.4869,4.7051ZM7.5835,5.1867C7.5813,4.9617 7.7862,4.7941 8.0001,4.7787C8.1419,4.8072 8.2965,4.8676 8.3573,5.0107C8.4707,5.2082 8.37,5.48 8.1651,5.5706C8.0714,5.6231 7.9607,5.6034 7.8586,5.5973C7.7027,5.5208 7.5713,5.3706 7.5835,5.1867ZM3.9976,5.5146C4.2056,5.3867 4.4862,5.62 4.4075,5.846C4.3641,6.0414 4.1014,6.1209 3.9512,5.9962C3.7909,5.8793 3.8163,5.5982 3.9976,5.5146ZM11.6978,5.5142C11.8742,5.3772 12.1654,5.5343 12.1444,5.7571C12.1562,5.9603 11.9045,6.1135 11.7293,6.0089C11.5364,5.9222 11.5167,5.6253 11.6978,5.5142ZM8.5919,5.9187C8.8831,5.814 9.2289,5.9392 9.3949,6.1988C9.6138,6.5162 9.4974,6.9995 9.1576,7.1816C8.8056,7.397 8.2916,7.2144 8.1615,6.8213C8.014,6.4694 8.229,6.029 8.5919,5.9187ZM6.8834,5.9533C7.2062,5.8009 7.6405,5.9287 7.7964,6.2589C7.9798,6.5802 7.838,7.0276 7.51,7.1935C7.1816,7.38 6.7183,7.2386 6.5594,6.8936C6.3812,6.56 6.5395,6.1069 6.8834,5.9533ZM5.1728,6.5381C5.1973,6.3302 5.3934,6.1949 5.5913,6.1809C5.8046,6.2066 5.9749,6.3722 5.9981,6.588C5.9841,6.8016 5.819,7.0104 5.5926,7.0091C5.3436,7.0306 5.1252,6.7828 5.1728,6.5381ZM10.2255,6.2261C10.4812,6.0773 10.8363,6.2939 10.8249,6.5877C10.8425,6.8989 10.4495,7.1183 10.1949,6.9357C9.9304,6.7837 9.951,6.3555 10.2255,6.2261ZM6.1882,7.3231C6.4872,7.2408 6.8292,7.3818 6.9759,7.6566C7.1365,7.9333 7.0708,8.3177 6.8213,8.5206C6.5013,8.8183 5.911,8.6988 5.7407,8.2926C5.545,7.9201 5.7827,7.4211 6.1882,7.3231ZM9.4286,7.3215C9.7194,7.2384 10.0609,7.3504 10.2172,7.6153C10.4238,7.9182 10.3252,8.37 10.0176,8.5653C9.6953,8.792 9.1961,8.673 9.0188,8.3184C8.8038,7.9517 9.0202,7.4334 9.4286,7.3215ZM4.2647,7.6671C4.523,7.5694 4.8094,7.8545 4.7047,8.1106C4.6408,8.3439 4.312,8.4302 4.1421,8.2581C3.9433,8.0966 4.0169,7.7372 4.2647,7.6671ZM11.2667,8.0388C11.2593,7.8247 11.4159,7.6352 11.6354,7.6234C11.8123,7.6514 11.9843,7.7941 11.9703,7.9867C11.9865,8.2411 11.68,8.414 11.4633,8.2944C11.3617,8.2428 11.3096,8.1386 11.2667,8.0388ZM2.9945,7.7928C3.1499,7.7249 3.3422,7.8596 3.3067,8.0322C3.2983,8.2276 3.0098,8.3028 2.9038,8.1395C2.8102,8.0261 2.8662,7.8512 2.9945,7.7928ZM12.7939,7.7889C12.9033,7.7109 13.0789,7.767 13.1223,7.8948C13.1958,8.0344 13.061,8.2257 12.9038,8.2021C12.6832,8.2222 12.6118,7.886 12.7939,7.7889ZM7.0323,8.727C7.4413,8.6206 7.8809,8.9616 7.8835,9.3827C7.9102,9.8083 7.4772,10.1856 7.0585,10.0873C6.735,10.0352 6.4811,9.7235 6.4915,9.3965C6.4907,9.0838 6.7267,8.7931 7.0323,8.727ZM8.6519,8.7261C9.067,8.6101 9.5197,8.9572 9.5131,9.388C9.5351,9.8057 9.1156,10.1703 8.7057,10.0875C8.32,10.0376 8.0354,9.6138 8.1431,9.2395C8.1974,8.9901 8.4058,8.7872 8.6519,8.7261ZM5.5292,8.9853C5.8165,8.9363 6.0857,9.2567 5.9692,9.5295C5.8843,9.8201 5.4613,9.8989 5.2743,9.6615C5.055,9.4335 5.2187,9.0168 5.5292,8.9853ZM10.2789,8.9981C10.535,8.8908 10.8494,9.1124 10.8297,9.3904C10.84,9.6964 10.4519,9.9074 10.2014,9.7288C9.9177,9.5684 9.9694,9.0965 10.2789,8.9981ZM11.6065,10.3297C11.5062,10.1427 11.6884,9.895 11.8959,9.9296C11.9993,9.9278 12.0715,10.0092 12.1377,10.0775C12.1512,10.1883 12.174,10.3205 12.0821,10.4059C11.9572,10.5639 11.6743,10.5188 11.6065,10.3297ZM3.9968,9.9816C4.1907,9.8525 4.4699,10.0451 4.4263,10.2719C4.4031,10.4725 4.1504,10.5871 3.984,10.4733C3.8054,10.37 3.812,10.0758 3.9968,9.9816ZM7.8292,10.4015C8.0832,10.2894 8.4067,10.5105 8.3826,10.7902C8.4015,11.0993 8.0013,11.3134 7.753,11.1278C7.4772,10.9684 7.5232,10.4995 7.8292,10.4015ZM6.0542,10.8156C6.2705,10.7018 6.5607,10.8983 6.541,11.1404C6.5476,11.3392 6.3536,11.5086 6.1575,11.4792C5.995,11.4757 5.8891,11.3301 5.837,11.1916C5.8396,11.0406 5.9018,10.8725 6.0542,10.8156ZM9.6497,10.8191C9.8722,10.6816 10.1883,10.8791 10.1673,11.1379C10.173,11.4085 9.8157,11.5818 9.6086,11.4041C9.4081,11.2648 9.4326,10.9299 9.6497,10.8191ZM10.275,12.3649C10.1761,12.2152 10.2925,12.0348 10.4532,12.0007C10.5824,12.0269 10.719,12.1241 10.6918,12.2739C10.673,12.4765 10.3766,12.5387 10.275,12.3649ZM5.3116,12.2349C5.351,12.1162 5.4464,11.9983 5.5861,12.0292C5.7897,12.0436 5.8501,12.3505 5.6719,12.4451C5.5117,12.5531 5.3258,12.4051 5.3116,12.2349ZM7.7062,12.371C7.7451,12.1955 7.9723,12.1101 8.1221,12.2033C8.2211,12.2458 8.25,12.3565 8.2754,12.4507C8.2618,12.4997 8.2496,12.5487 8.2377,12.5978C8.1764,12.6704 8.0976,12.7431 7.9956,12.7405C7.806,12.7627 7.6349,12.5483 7.7062,12.371Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#0033AD" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#ffffff" android:pathData="M7.8738,3.2662C8.098,3.1493 8.3717,3.4204 8.2526,3.6444C8.1834,3.827 7.9211,3.8755 7.7871,3.7364C7.6452,3.6028 7.6915,3.3388 7.8738,3.2662ZM5.4626,3.5261C5.5988,3.47 5.7712,3.5948 5.7573,3.7432C5.7718,3.9043 5.5747,4.0229 5.4359,3.9464C5.252,3.8751 5.273,3.5766 5.4626,3.5261ZM10.4011,3.9509C10.1883,3.9252 10.1546,3.5906 10.3595,3.5232C10.5184,3.4457 10.6642,3.591 10.6875,3.7417C10.6541,3.8703 10.5465,3.9881 10.4011,3.9509ZM6.0113,4.5523C6.2389,4.4083 6.5638,4.6228 6.5288,4.8872C6.517,5.1543 6.1623,5.309 5.9622,5.1284C5.7687,4.9867 5.798,4.6614 6.0113,4.5523ZM9.4869,4.7051C9.5884,4.4434 10,4.4354 10.1156,4.6903C10.2299,4.8886 10.0894,5.1342 9.8857,5.2016C9.616,5.2519 9.3599,4.9604 9.4869,4.7051ZM7.5835,5.1867C7.5813,4.9617 7.7862,4.7941 8.0001,4.7787C8.1419,4.8072 8.2965,4.8676 8.3573,5.0107C8.4707,5.2082 8.37,5.48 8.1651,5.5706C8.0714,5.6231 7.9607,5.6034 7.8586,5.5973C7.7027,5.5208 7.5713,5.3706 7.5835,5.1867ZM3.9976,5.5146C4.2056,5.3867 4.4862,5.62 4.4075,5.846C4.3641,6.0414 4.1014,6.1209 3.9512,5.9962C3.7909,5.8793 3.8163,5.5982 3.9976,5.5146ZM11.6978,5.5142C11.8742,5.3772 12.1654,5.5343 12.1444,5.7571C12.1562,5.9603 11.9045,6.1135 11.7293,6.0089C11.5364,5.9222 11.5167,5.6253 11.6978,5.5142ZM8.5919,5.9187C8.8831,5.814 9.2289,5.9392 9.3949,6.1988C9.6138,6.5162 9.4974,6.9995 9.1576,7.1816C8.8056,7.397 8.2916,7.2144 8.1615,6.8213C8.014,6.4694 8.229,6.029 8.5919,5.9187ZM6.8834,5.9533C7.2062,5.8009 7.6405,5.9287 7.7964,6.2589C7.9798,6.5802 7.838,7.0276 7.51,7.1935C7.1816,7.38 6.7183,7.2386 6.5594,6.8936C6.3812,6.56 6.5395,6.1069 6.8834,5.9533ZM5.1728,6.5381C5.1973,6.3302 5.3934,6.1949 5.5913,6.1809C5.8046,6.2066 5.9749,6.3722 5.9981,6.588C5.9841,6.8016 5.819,7.0104 5.5926,7.0091C5.3436,7.0306 5.1252,6.7828 5.1728,6.5381ZM10.2255,6.2261C10.4812,6.0773 10.8363,6.2939 10.8249,6.5877C10.8425,6.8989 10.4495,7.1183 10.1949,6.9357C9.9304,6.7837 9.951,6.3555 10.2255,6.2261ZM6.1882,7.3231C6.4872,7.2408 6.8292,7.3818 6.9759,7.6566C7.1365,7.9333 7.0708,8.3177 6.8213,8.5206C6.5013,8.8183 5.911,8.6988 5.7407,8.2926C5.545,7.9201 5.7827,7.4211 6.1882,7.3231ZM9.4286,7.3215C9.7194,7.2384 10.0609,7.3504 10.2172,7.6153C10.4238,7.9182 10.3252,8.37 10.0176,8.5653C9.6953,8.792 9.1961,8.673 9.0188,8.3184C8.8038,7.9517 9.0202,7.4334 9.4286,7.3215ZM4.2647,7.6671C4.523,7.5694 4.8094,7.8545 4.7047,8.1106C4.6408,8.3439 4.312,8.4302 4.1421,8.2581C3.9433,8.0966 4.0169,7.7372 4.2647,7.6671ZM11.2667,8.0388C11.2593,7.8247 11.4159,7.6352 11.6354,7.6234C11.8123,7.6514 11.9843,7.7941 11.9703,7.9867C11.9865,8.2411 11.68,8.414 11.4633,8.2944C11.3617,8.2428 11.3096,8.1386 11.2667,8.0388ZM2.9945,7.7928C3.1499,7.7249 3.3422,7.8596 3.3067,8.0322C3.2983,8.2276 3.0098,8.3028 2.9038,8.1395C2.8102,8.0261 2.8662,7.8512 2.9945,7.7928ZM12.7939,7.7889C12.9033,7.7109 13.0789,7.767 13.1223,7.8948C13.1958,8.0344 13.061,8.2257 12.9038,8.2021C12.6832,8.2222 12.6118,7.886 12.7939,7.7889ZM7.0323,8.727C7.4413,8.6206 7.8809,8.9616 7.8835,9.3827C7.9102,9.8083 7.4772,10.1856 7.0585,10.0873C6.735,10.0352 6.4811,9.7235 6.4915,9.3965C6.4907,9.0838 6.7267,8.7931 7.0323,8.727ZM8.6519,8.7261C9.067,8.6101 9.5197,8.9572 9.5131,9.388C9.5351,9.8057 9.1156,10.1703 8.7057,10.0875C8.32,10.0376 8.0354,9.6138 8.1431,9.2395C8.1974,8.9901 8.4058,8.7872 8.6519,8.7261ZM5.5292,8.9853C5.8165,8.9363 6.0857,9.2567 5.9692,9.5295C5.8843,9.8201 5.4613,9.8989 5.2743,9.6615C5.055,9.4335 5.2187,9.0168 5.5292,8.9853ZM10.2789,8.9981C10.535,8.8908 10.8494,9.1124 10.8297,9.3904C10.84,9.6964 10.4519,9.9074 10.2014,9.7288C9.9177,9.5684 9.9694,9.0965 10.2789,8.9981ZM11.6065,10.3297C11.5062,10.1427 11.6884,9.895 11.8959,9.9296C11.9993,9.9278 12.0715,10.0092 12.1377,10.0775C12.1512,10.1883 12.174,10.3205 12.0821,10.4059C11.9572,10.5639 11.6743,10.5188 11.6065,10.3297ZM3.9968,9.9816C4.1907,9.8525 4.4699,10.0451 4.4263,10.2719C4.4031,10.4725 4.1504,10.5871 3.984,10.4733C3.8054,10.37 3.812,10.0758 3.9968,9.9816ZM7.8292,10.4015C8.0832,10.2894 8.4067,10.5105 8.3826,10.7902C8.4015,11.0993 8.0013,11.3134 7.753,11.1278C7.4772,10.9684 7.5232,10.4995 7.8292,10.4015ZM6.0542,10.8156C6.2705,10.7018 6.5607,10.8983 6.541,11.1404C6.5476,11.3392 6.3536,11.5086 6.1575,11.4792C5.995,11.4757 5.8891,11.3301 5.837,11.1916C5.8396,11.0406 5.9018,10.8725 6.0542,10.8156ZM9.6497,10.8191C9.8722,10.6816 10.1883,10.8791 10.1673,11.1379C10.173,11.4085 9.8157,11.5818 9.6086,11.4041C9.4081,11.2648 9.4326,10.9299 9.6497,10.8191ZM10.275,12.3649C10.1761,12.2152 10.2925,12.0348 10.4532,12.0007C10.5824,12.0269 10.719,12.1241 10.6918,12.2739C10.673,12.4765 10.3766,12.5387 10.275,12.3649ZM5.3116,12.2349C5.351,12.1162 5.4464,11.9983 5.5861,12.0292C5.7897,12.0436 5.8501,12.3505 5.6719,12.4451C5.5117,12.5531 5.3258,12.4051 5.3116,12.2349ZM7.7062,12.371C7.7451,12.1955 7.9723,12.1101 8.1221,12.2033C8.2211,12.2458 8.25,12.3565 8.2754,12.4507C8.2618,12.4997 8.2496,12.5487 8.2377,12.5978C8.1764,12.6704 8.0976,12.7431 7.9956,12.7405C7.806,12.7627 7.6349,12.5483 7.7062,12.371Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#A1A1A4" android:fillType="evenOdd" android:pathData="M5.3545,12.185H8.1164H8.1165C8.1165,12.185 11.9999,12.5157 11.9999,8.0674C11.9999,3.7917 8.4536,3.8068 7.7682,3.8098C7.7521,3.8098 7.7376,3.8099 7.7248,3.8099H5.3544V7.5406H4.3809V8.4545H5.3545V12.185ZM6.9101,5.3579H7.9998C8.4074,5.3579 10.4578,5.5245 10.4611,8.0975C10.4643,10.6399 8.397,10.6373 8.0645,10.6368C8.0604,10.6368 8.0567,10.6368 8.0532,10.6368H6.9101V8.4544H8.6245V7.5405H6.9101V5.3579Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#C2A633" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#ffffff" android:fillType="evenOdd" android:pathData="M5.3545,12.185H8.1164H8.1165C8.1165,12.185 11.9999,12.5157 11.9999,8.0674C11.9999,3.7917 8.4536,3.8068 7.7682,3.8098C7.7521,3.8098 7.7376,3.8099 7.7248,3.8099H5.3544V7.5406H4.3809V8.4545H5.3545V12.185ZM6.9101,5.3579H7.9998C8.4074,5.3579 10.4578,5.5245 10.4611,8.0975C10.4643,10.6399 8.397,10.6373 8.0645,10.6368C8.0604,10.6368 8.0567,10.6368 8.0532,10.6368H6.9101V8.4544H8.6245V7.5405H6.9101V5.3579Z"/>
</vector>

View file

@ -0,0 +1,14 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:pathData="M8,16C12.4183,16 16,12.4183 16,8C16,3.5817 12.4183,0 8,0C3.5817,0 0,3.5817 0,8C0,12.4183 3.5817,16 8,16Z"/>
<group>
<clip-path android:pathData="M8.0002,2.8001L8.0002,2.8001A3.2001,3.2001 0,0 1,11.2003 6.0001L11.2003,10.0003A3.2001,3.2001 0,0 1,8.0002 13.2003L8.0002,13.2003A3.2001,3.2001 0,0 1,4.8002 10.0003L4.8002,6.0001A3.2001,3.2001 0,0 1,8.0002 2.8001z"/>
<path android:fillColor="#A1A1A4" android:pathData="M7.9994,2.8001L7.9296,3.037V9.9123L7.9994,9.9819L11.1986,8.0955L7.9994,2.8001Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M7.9993,2.8001L4.8002,8.0955L7.9993,9.9819V6.6449V2.8001Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M7.9992,10.5862L7.9598,10.6341V13.0832L7.9992,13.198L11.2003,8.7007L7.9992,10.5862Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M7.9993,13.1982V10.5864L4.8002,8.7009L7.9993,13.1982Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M7.9991,9.9821L11.1982,8.0956L7.9991,6.645V9.9821Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M4.8002,8.0956L7.9992,9.9821V6.645L4.8002,8.0956Z"/>
</group>
</vector>

View file

@ -0,0 +1,20 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:pathData="M8,16C12.4183,16 16,12.4183 16,8C16,3.5817 12.4183,0 8,0C3.5817,0 0,3.5817 0,8C0,12.4183 3.5817,16 8,16Z"/>
<group>
<clip-path android:pathData="M8,2.8001L8,2.8001A3.2,3.2 0,0 1,11.2001 6.0001L11.2001,10A3.2,3.2 0,0 1,8 13.2001L8,13.2001A3.2,3.2 0,0 1,4.8 10L4.8,6.0001A3.2,3.2 0,0 1,8 2.8001z"/>
<path android:fillAlpha="0.8" android:fillColor="#343434"
android:pathData="M7.9992,2.8001L7.9293,3.037V9.9122L7.9992,9.9817L11.1982,8.0953L7.9992,2.8001Z" android:strokeAlpha="0.8"/>
<path android:fillAlpha="0.8" android:fillColor="#8C8C8C"
android:pathData="M7.9991,2.8001L4.8,8.0953L7.9991,9.9818V6.6448V2.8001Z" android:strokeAlpha="0.8"/>
<path android:fillAlpha="0.8" android:fillColor="#3C3C3B"
android:pathData="M7.999,10.5862L7.9596,10.634V13.0831L7.999,13.1978L11.1999,8.7007L7.999,10.5862Z" android:strokeAlpha="0.8"/>
<path android:fillAlpha="0.8" android:fillColor="#8C8C8C"
android:pathData="M7.9991,13.1979V10.5862L4.8,8.7007L7.9991,13.1979Z" android:strokeAlpha="0.8"/>
<path android:fillAlpha="0.8" android:fillColor="#141414"
android:pathData="M7.999,9.9817L11.198,8.0953L7.999,6.6448V9.9817Z" android:strokeAlpha="0.8"/>
<path android:fillAlpha="0.8" android:fillColor="#393939"
android:pathData="M4.8,8.0953L7.9991,9.9818V6.6448L4.8,8.0953Z" android:strokeAlpha="0.8"/>
</group>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="22dp"
android:viewportHeight="22" android:viewportWidth="22"
android:width="22dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:pathData="M11,22C17.0751,22 22,17.0751 22,11C22,4.9249 17.0751,0 11,0C4.9249,0 0,4.9249 0,11C0,17.0751 4.9249,22 11,22Z"/>
<path android:fillColor="#A1A1A4" android:fillType="evenOdd" android:pathData="M11.825,8.8687L14.3,7.425V10.3125L11.825,8.8687ZM14.3,15.0562L11,16.9813L7.7,15.0562V11.6875L11,13.6125L14.3,11.6875V15.0562ZM7.7,7.425L10.175,8.8687L7.7,10.3125V7.425ZM11.4125,9.5562L13.8875,11L11.4125,12.4438V9.5562ZM10.5875,12.4438L8.1125,11L10.5875,9.5562V12.4438ZM13.8875,6.7375L11,8.3875L8.1125,6.7375L11,5.0188L13.8875,6.7375ZM6.875,6.4625V15.4688L11,17.8062L15.125,15.4688V6.4625L11,4.125L6.875,6.4625Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="22dp"
android:viewportHeight="22" android:viewportWidth="22"
android:width="22dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#13B5EC" android:pathData="M11,22C17.0751,22 22,17.0751 22,11C22,4.9249 17.0751,0 11,0C4.9249,0 0,4.9249 0,11C0,17.0751 4.9249,22 11,22Z"/>
<path android:fillColor="#F8F9F9" android:fillType="evenOdd" android:pathData="M11.825,8.8687L14.3,7.425V10.3125L11.825,8.8687ZM14.3,15.0562L11,16.9813L7.7,15.0562V11.6875L11,13.6125L14.3,11.6875V15.0562ZM7.7,7.425L10.175,8.8687L7.7,10.3125V7.425ZM11.4125,9.5562L13.8875,11L11.4125,12.4438V9.5562ZM10.5875,12.4438L8.1125,11L10.5875,9.5562V12.4438ZM13.8875,6.7375L11,8.3875L8.1125,6.7375L11,5.0188L13.8875,6.7375ZM6.875,6.4625V15.4688L11,17.8062L15.125,15.4688V6.4625L11,4.125L6.875,6.4625Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#A1A1A4" android:pathData="M12.4155,5.3206C12.265,5.2041 12.0856,5.0449 11.7587,5.0051C11.452,4.9653 11.1395,5.1671 10.9282,5.3007C10.717,5.4343 10.3177,5.8266 10.1528,5.946C9.9879,6.0654 9.5654,6.1762 8.8854,6.577C8.2054,6.9778 5.5376,8.6606 5.5376,8.6606L6.2321,8.6691L3.136,10.2354H3.4456L3,10.5679C3,10.5679 3.3935,10.6703 3.7234,10.4656V10.5594C3.7234,10.5594 7.4097,9.1325 8.1215,9.502L7.6875,9.6271C7.7251,9.6271 8.4254,9.6725 8.4254,9.6725C8.4423,9.815 8.4911,9.952 8.5681,10.0738C8.6451,10.1957 8.7485,10.2994 8.8709,10.3775C9.2934,10.6504 9.3021,10.801 9.3021,10.801C9.3021,10.801 9.0822,10.8891 9.0822,11C9.0822,11 9.4063,10.9034 9.7072,10.9119C9.8982,10.919 10.0876,10.9486 10.2714,11C10.2714,11 10.2483,10.8806 9.956,10.801C9.6638,10.7214 9.3744,10.4088 9.2326,10.2382C9.1458,10.1296 9.0892,10.0008 9.0684,9.8642C9.0476,9.7276 9.0633,9.5881 9.114,9.4593C9.2153,9.2007 9.5683,9.0585 10.2975,8.689C11.1568,8.2513 11.3536,7.9272 11.4751,7.6742C11.5966,7.4212 11.776,6.9181 11.8773,6.6822C12.0046,6.378 12.1609,6.216 12.2911,6.1194C12.4213,6.0227 13,5.8095 13,5.8095C13,5.8095 12.5573,5.4315 12.4155,5.3206Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#000000" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#ffffff" android:pathData="M12.4155,5.3206C12.265,5.2041 12.0856,5.0449 11.7587,5.0051C11.452,4.9653 11.1395,5.1671 10.9282,5.3007C10.717,5.4343 10.3177,5.8266 10.1528,5.946C9.9879,6.0654 9.5654,6.1762 8.8854,6.577C8.2054,6.9778 5.5376,8.6606 5.5376,8.6606L6.2321,8.6691L3.136,10.2354H3.4456L3,10.5679C3,10.5679 3.3935,10.6703 3.7234,10.4656V10.5594C3.7234,10.5594 7.4097,9.1325 8.1215,9.502L7.6875,9.6271C7.7251,9.6271 8.4254,9.6725 8.4254,9.6725C8.4423,9.815 8.4911,9.952 8.5681,10.0738C8.6451,10.1957 8.7485,10.2994 8.8709,10.3775C9.2934,10.6504 9.3021,10.801 9.3021,10.801C9.3021,10.801 9.0822,10.8891 9.0822,11C9.0822,11 9.4063,10.9034 9.7072,10.9119C9.8982,10.919 10.0876,10.9486 10.2714,11C10.2714,11 10.2483,10.8806 9.956,10.801C9.6638,10.7214 9.3744,10.4088 9.2326,10.2382C9.1458,10.1296 9.0892,10.0008 9.0684,9.8642C9.0476,9.7276 9.0633,9.5881 9.114,9.4593C9.2153,9.2007 9.5683,9.0585 10.2975,8.689C11.1568,8.2513 11.3536,7.9272 11.4751,7.6742C11.5966,7.4212 11.776,6.9181 11.8773,6.6822C12.0046,6.378 12.1609,6.216 12.2911,6.1194C12.4213,6.0227 13,5.8095 13,5.8095C13,5.8095 12.5573,5.4315 12.4155,5.3206Z"/>
</vector>

View file

@ -0,0 +1,10 @@
<vector android:autoMirrored="true" android:height="38dp"
android:viewportHeight="38" android:viewportWidth="32"
android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#00000000"
android:pathData="M1,0L1,14C1,25.0457 9.9543,34 21,34H30"
android:strokeColor="#DEDEDE" android:strokeWidth="1"/>
<path android:fillColor="#DEDEDE"
android:pathData="M26.75,31.8822V36.1185L30.8871,34.0004L26.75,31.8822Z"
android:strokeColor="#DEDEDE" android:strokeWidth="1.5"/>
</vector>

View file

@ -0,0 +1,10 @@
<vector android:autoMirrored="true" android:height="89dp"
android:viewportHeight="89" android:viewportWidth="32"
android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#00000000"
android:pathData="M1,0L1,65C1,76.0457 9.9543,85 21,85H30"
android:strokeColor="#DEDEDE" android:strokeWidth="1"/>
<path android:fillColor="#DEDEDE"
android:pathData="M26.75,82.8822V87.1185L30.8871,85.0004L26.75,82.8822Z"
android:strokeColor="#DEDEDE" android:strokeWidth="1.5"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<group>
<clip-path android:pathData="M0,0h16v16h-16z"/>
<path android:fillColor="#A1A1A4" android:pathData="M8,16C12.4183,16 16,12.4183 16,8C16,3.5817 12.4183,0 8,0C3.5817,0 0,3.5817 0,8C0,12.4183 3.5817,16 8,16Z"/>
<path android:fillColor="#F1F1F1" android:pathData="M8,0C6.4177,0 4.871,0.4692 3.5554,1.3482C2.2399,2.2273 1.2145,3.4767 0.609,4.9385C0.0035,6.4003 -0.155,8.0089 0.1537,9.5607C0.4624,11.1126 1.2243,12.538 2.3431,13.6569C3.462,14.7757 4.8874,15.5376 6.4393,15.8463C7.9911,16.155 9.5997,15.9965 11.0615,15.391C12.5233,14.7855 13.7727,13.7602 14.6518,12.4446C15.5308,11.129 16,9.5822 16,8C16.0031,6.9525 15.7998,5.9146 15.4017,4.9457C15.0037,3.9767 14.4187,3.0956 13.6801,2.3528C12.9416,1.6099 12.0639,1.0198 11.0973,0.6161C10.1307,0.2124 9.094,0.003 8.0465,0H8ZM8.1356,8.2712L7.3027,11.0799H11.7579C11.7874,11.0789 11.8168,11.0837 11.8445,11.094C11.8721,11.1044 11.8975,11.12 11.9191,11.1402C11.9407,11.1603 11.9581,11.1846 11.9703,11.2114C11.9825,11.2383 11.9893,11.2673 11.9903,11.2969V11.3705L11.6029,12.707C11.5858,12.7702 11.5478,12.8257 11.495,12.8645C11.4422,12.9032 11.3778,12.9228 11.3124,12.9201H4.4939L5.6368,9.0266L4.3584,9.414L4.6489,8.523L5.9274,8.1356L7.5351,2.6731C7.5528,2.6103 7.591,2.5552 7.6437,2.5165C7.6963,2.4779 7.7604,2.458 7.8257,2.4601H9.5496C9.5792,2.459 9.6086,2.4638 9.6362,2.4741C9.6639,2.4845 9.6892,2.5002 9.7108,2.5203C9.7324,2.5405 9.7498,2.5647 9.762,2.5916C9.7743,2.6185 9.7811,2.6475 9.7821,2.677V2.7506L8.4262,7.3608L9.7046,6.9734L9.4334,7.9032L8.1356,8.2712Z"/>
</group>
</vector>

View file

@ -0,0 +1,9 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<group>
<clip-path android:pathData="M0,0h16v16h-16z"/>
<path android:fillColor="#ffffff" android:pathData="M8,16C12.4183,16 16,12.4183 16,8C16,3.5817 12.4183,0 8,0C3.5817,0 0,3.5817 0,8C0,12.4183 3.5817,16 8,16Z"/>
<path android:fillColor="#345D9D" android:pathData="M8,0C6.4177,0 4.871,0.4692 3.5554,1.3482C2.2399,2.2273 1.2145,3.4767 0.609,4.9385C0.0035,6.4003 -0.155,8.0089 0.1537,9.5607C0.4624,11.1126 1.2243,12.538 2.3431,13.6569C3.462,14.7757 4.8874,15.5376 6.4393,15.8463C7.9911,16.155 9.5997,15.9965 11.0615,15.391C12.5233,14.7855 13.7727,13.7602 14.6518,12.4446C15.5308,11.129 16,9.5822 16,8C16.0031,6.9525 15.7998,5.9146 15.4017,4.9457C15.0037,3.9767 14.4187,3.0956 13.6801,2.3528C12.9416,1.6099 12.0639,1.0198 11.0973,0.6161C10.1307,0.2124 9.094,0.003 8.0465,0H8ZM8.1356,8.2712L7.3027,11.0799H11.7579C11.7874,11.0789 11.8168,11.0837 11.8445,11.094C11.8721,11.1044 11.8975,11.12 11.9191,11.1402C11.9407,11.1603 11.9581,11.1846 11.9703,11.2114C11.9825,11.2383 11.9893,11.2673 11.9903,11.2969V11.3705L11.6029,12.707C11.5858,12.7702 11.5478,12.8257 11.495,12.8645C11.4422,12.9032 11.3778,12.9228 11.3124,12.9201H4.4939L5.6368,9.0266L4.3584,9.414L4.6489,8.523L5.9274,8.1356L7.5351,2.6731C7.5528,2.6103 7.591,2.5552 7.6437,2.5165C7.6963,2.4779 7.7604,2.458 7.8257,2.4601H9.5496C9.5792,2.459 9.6086,2.4638 9.6362,2.4741C9.6639,2.4845 9.6892,2.5002 9.7108,2.5203C9.7324,2.5405 9.7498,2.5647 9.762,2.5916C9.7743,2.6185 9.7811,2.6475 9.7821,2.677V2.7506L8.4262,7.3608L9.7046,6.9734L9.4334,7.9032L8.1356,8.2712Z"/>
</group>
</vector>

View file

@ -0,0 +1,11 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#A1A1A4" android:pathData="M7.9994,4.5169C9.2703,4.5169 10.3006,3.9535 10.3006,3.2585C10.3006,2.5634 9.2703,2 7.9994,2C6.7285,2 5.6982,2.5634 5.6982,3.2585C5.6982,3.9535 6.7285,4.5169 7.9994,4.5169Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M7.9994,13.9991C9.2703,13.9991 10.3006,13.4357 10.3006,12.7406C10.3006,12.0456 9.2703,11.4822 7.9994,11.4822C6.7285,11.4822 5.6982,12.0456 5.6982,12.7406C5.6982,13.4357 6.7285,13.9991 7.9994,13.9991Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M4.7927,6.259C5.4282,5.2241 5.424,4.1032 4.7835,3.7555C4.1429,3.4077 3.1086,3.9648 2.4731,4.9997C1.8376,6.0346 1.8418,7.1554 2.4823,7.5032C3.1228,7.8509 4.1572,7.2939 4.7927,6.259Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M13.5251,10.9994C14.1605,9.9645 14.1567,8.8438 13.5166,8.4963C12.8765,8.1488 11.8425,8.706 11.207,9.7409C10.5715,10.7758 10.5753,11.8965 11.2154,12.244C11.8555,12.5915 12.8896,12.0343 13.5251,10.9994Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M4.7837,12.2438C5.4243,11.896 5.4284,10.7752 4.793,9.7403C4.1575,8.7054 3.1231,8.1483 2.4826,8.4961C1.842,8.8438 1.8379,9.9647 2.4733,10.9996C3.1088,12.0345 4.1432,12.5915 4.7837,12.2438Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M13.517,7.5035C14.1571,7.156 14.1609,6.0353 13.5255,5.0004C12.89,3.9655 11.856,3.4083 11.2159,3.7558C10.5758,4.1033 10.572,5.224 11.2075,6.2589C11.8429,7.2938 12.8769,7.851 13.517,7.5035Z"/>
</vector>

View file

@ -0,0 +1,11 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FEF2F8" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#E6007A" android:pathData="M7.9994,4.5169C9.2703,4.5169 10.3006,3.9535 10.3006,3.2585C10.3006,2.5634 9.2703,2 7.9994,2C6.7285,2 5.6982,2.5634 5.6982,3.2585C5.6982,3.9535 6.7285,4.5169 7.9994,4.5169Z"/>
<path android:fillColor="#E6007A" android:pathData="M7.9994,13.9991C9.2703,13.9991 10.3006,13.4357 10.3006,12.7406C10.3006,12.0456 9.2703,11.4822 7.9994,11.4822C6.7285,11.4822 5.6982,12.0456 5.6982,12.7406C5.6982,13.4357 6.7285,13.9991 7.9994,13.9991Z"/>
<path android:fillColor="#E6007A" android:pathData="M4.7927,6.259C5.4282,5.2241 5.424,4.1032 4.7835,3.7555C4.1429,3.4077 3.1086,3.9648 2.4731,4.9997C1.8376,6.0346 1.8418,7.1554 2.4823,7.5032C3.1228,7.8509 4.1572,7.2939 4.7927,6.259Z"/>
<path android:fillColor="#E6007A" android:pathData="M13.5251,10.9994C14.1605,9.9645 14.1567,8.8438 13.5166,8.4963C12.8765,8.1488 11.8425,8.706 11.207,9.7409C10.5715,10.7758 10.5753,11.8965 11.2154,12.244C11.8555,12.5915 12.8896,12.0343 13.5251,10.9994Z"/>
<path android:fillColor="#E6007A" android:pathData="M4.7837,12.2438C5.4243,11.896 5.4284,10.7752 4.793,9.7403C4.1575,8.7054 3.1231,8.1483 2.4826,8.4961C1.842,8.8438 1.8379,9.9647 2.4733,10.9996C3.1088,12.0345 4.1432,12.5915 4.7837,12.2438Z"/>
<path android:fillColor="#E6007A" android:pathData="M13.517,7.5035C14.1571,7.156 14.1609,6.0353 13.5255,5.0004C12.89,3.9655 11.856,3.4083 11.2159,3.7558C10.5758,4.1033 10.572,5.224 11.2075,6.2589C11.8429,7.2938 12.8769,7.851 13.517,7.5035Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:pathData="M8,16C12.4183,16 16,12.4183 16,8C16,3.5817 12.4183,0 8,0C3.5817,0 0,3.5817 0,8C0,12.4183 3.5817,16 8,16Z"/>
<path android:fillColor="#A1A1A4" android:pathData="M10.6283,6.3937C10.4378,6.2889 10.1902,6.2889 9.9808,6.3937L8.4952,7.1968L7.4858,7.7205L6.0003,8.5237C5.8098,8.6284 5.5622,8.6284 5.3527,8.5237L4.1719,7.8951C3.9815,7.7904 3.8482,7.5983 3.8482,7.3888V6.1492C3.8482,5.9397 3.9624,5.7477 4.1719,5.6429L5.3337,5.0319C5.5241,4.9271 5.7717,4.9271 5.9812,5.0319L7.143,5.6429C7.3335,5.7477 7.4668,5.9397 7.4668,6.1492V6.9524L8.4762,6.4111V5.608C8.4762,5.3985 8.3619,5.2064 8.1524,5.1017L6.0003,3.9494C5.8098,3.8447 5.5622,3.8447 5.3527,3.9494L3.1625,5.1017C2.953,5.2064 2.8387,5.3985 2.8387,5.608V7.93C2.8387,8.1395 2.953,8.3316 3.1625,8.4363L5.3527,9.5886C5.5432,9.6934 5.7908,9.6934 6.0003,9.5886L7.4858,8.803L8.4952,8.2618L9.9808,7.4761C10.1712,7.3714 10.4188,7.3714 10.6283,7.4761L11.7901,8.0872C11.9805,8.1919 12.1138,8.384 12.1138,8.5935V9.8331C12.1138,10.0426 11.9996,10.2346 11.7901,10.3394L10.6283,10.9679C10.4378,11.0727 10.1902,11.0727 9.9808,10.9679L8.819,10.3568C8.6285,10.2521 8.4952,10.06 8.4952,9.8505V9.0474L7.4858,9.5886V10.3917C7.4858,10.6013 7.6001,10.7933 7.8096,10.8981L9.9998,12.0504C10.1902,12.1551 10.4378,12.1551 10.6473,12.0504L12.8376,10.8981C13.028,10.7933 13.1613,10.6013 13.1613,10.3917V8.0697C13.1613,7.8602 13.0471,7.6682 12.8376,7.5634L10.6283,6.3937Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#8247E5" android:pathData="M8,16C12.4183,16 16,12.4183 16,8C16,3.5817 12.4183,0 8,0C3.5817,0 0,3.5817 0,8C0,12.4183 3.5817,16 8,16Z"/>
<path android:fillColor="#ffffff" android:pathData="M10.6283,6.3937C10.4378,6.2889 10.1902,6.2889 9.9808,6.3937L8.4952,7.1968L7.4858,7.7205L6.0003,8.5237C5.8098,8.6284 5.5622,8.6284 5.3527,8.5237L4.1719,7.8951C3.9815,7.7904 3.8482,7.5983 3.8482,7.3888V6.1492C3.8482,5.9397 3.9624,5.7477 4.1719,5.6429L5.3337,5.0319C5.5241,4.9271 5.7717,4.9271 5.9812,5.0319L7.143,5.6429C7.3335,5.7477 7.4668,5.9397 7.4668,6.1492V6.9524L8.4762,6.4111V5.608C8.4762,5.3985 8.3619,5.2064 8.1524,5.1017L6.0003,3.9494C5.8098,3.8447 5.5622,3.8447 5.3527,3.9494L3.1625,5.1017C2.953,5.2064 2.8387,5.3985 2.8387,5.608V7.93C2.8387,8.1395 2.953,8.3316 3.1625,8.4363L5.3527,9.5886C5.5432,9.6934 5.7908,9.6934 6.0003,9.5886L7.4858,8.803L8.4952,8.2618L9.9808,7.4761C10.1712,7.3714 10.4188,7.3714 10.6283,7.4761L11.7901,8.0872C11.9805,8.1919 12.1138,8.384 12.1138,8.5935V9.8331C12.1138,10.0426 11.9996,10.2346 11.7901,10.3394L10.6283,10.9679C10.4378,11.0727 10.1902,11.0727 9.9808,10.9679L8.819,10.3568C8.6285,10.2521 8.4952,10.06 8.4952,9.8505V9.0474L7.4858,9.5886V10.3917C7.4858,10.6013 7.6001,10.7933 7.8096,10.8981L9.9998,12.0504C10.1902,12.1551 10.4378,12.1551 10.6473,12.0504L12.8376,10.8981C13.028,10.7933 13.1613,10.6013 13.1613,10.3917V8.0697C13.1613,7.8602 13.0471,7.6682 12.8376,7.5634L10.6283,6.3937Z"/>
</vector>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:pathData="M8,0L8,0A8,8 0,0 1,16 8L16,8A8,8 0,0 1,8 16L8,16A8,8 0,0 1,0 8L0,8A8,8 0,0 1,8 0z"/>
<path android:fillColor="#A1A1A4" android:pathData="M12.3419,10.4366L10.8935,12.0202C10.862,12.0546 10.8239,12.082 10.7816,12.1008C10.7392,12.1195 10.6936,12.1292 10.6474,12.1292H3.7811C3.7483,12.1292 3.7163,12.1194 3.6889,12.1011C3.6615,12.0828 3.6399,12.0567 3.6268,12.0261C3.6138,11.9954 3.6098,11.9616 3.6154,11.9287C3.6209,11.8957 3.6358,11.8652 3.6581,11.8408L5.1077,10.2572C5.1391,10.2228 5.177,10.1955 5.2192,10.1767C5.2614,10.158 5.307,10.1483 5.353,10.1482H12.219C12.2517,10.1482 12.2838,10.158 12.3112,10.1763C12.3385,10.1946 12.3601,10.2207 12.3732,10.2513C12.3862,10.2819 12.3902,10.3158 12.3847,10.3487C12.3791,10.3816 12.3643,10.4122 12.3419,10.4366ZM10.8935,7.2476C10.862,7.2132 10.8239,7.1858 10.7816,7.167C10.7392,7.1483 10.6936,7.1386 10.6474,7.1387H3.7811C3.7483,7.1387 3.7163,7.1484 3.6889,7.1667C3.6615,7.1851 3.6399,7.2111 3.6268,7.2418C3.6138,7.2724 3.6098,7.3063 3.6154,7.3392C3.6209,7.3721 3.6358,7.4026 3.6581,7.4271L5.1077,9.0107C5.1391,9.045 5.177,9.0723 5.2192,9.0911C5.2614,9.1098 5.307,9.1195 5.353,9.1196H12.219C12.2517,9.1196 12.2838,9.1099 12.3112,9.0915C12.3385,9.0732 12.3601,9.0472 12.3732,9.0165C12.3862,8.9859 12.3902,8.952 12.3847,8.9191C12.3791,8.8862 12.3643,8.8557 12.3419,8.8312L10.8935,7.2476ZM3.7811,6.1101H10.6474C10.6936,6.1101 10.7392,6.1005 10.7816,6.0817C10.8239,6.063 10.862,6.0356 10.8935,6.0012L12.3419,4.4175C12.3643,4.3931 12.3791,4.3626 12.3847,4.3296C12.3902,4.2967 12.3862,4.2629 12.3732,4.2323C12.3601,4.2016 12.3385,4.1755 12.3112,4.1572C12.2838,4.1389 12.2517,4.1291 12.219,4.1291H5.353C5.307,4.1292 5.2614,4.1389 5.2192,4.1577C5.177,4.1764 5.1391,4.2038 5.1077,4.2381L3.6585,5.8217C3.6362,5.8461 3.6213,5.8766 3.6157,5.9095C3.6102,5.9424 3.6141,5.9762 3.6272,6.0068C3.6402,6.0374 3.6617,6.0635 3.689,6.0819C3.7163,6.1002 3.7483,6.11 3.7811,6.1101Z"/>
</vector>

View file

@ -0,0 +1,18 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#000000" android:pathData="M8,0L8,0A8,8 0,0 1,16 8L16,8A8,8 0,0 1,8 16L8,16A8,8 0,0 1,0 8L0,8A8,8 0,0 1,8 0z"/>
<path android:pathData="M12.3419,10.4366L10.8935,12.0202C10.862,12.0546 10.8239,12.082 10.7816,12.1008C10.7392,12.1195 10.6936,12.1292 10.6474,12.1292H3.7811C3.7483,12.1292 3.7163,12.1194 3.6889,12.1011C3.6615,12.0828 3.6399,12.0567 3.6268,12.0261C3.6138,11.9954 3.6098,11.9616 3.6154,11.9287C3.6209,11.8957 3.6358,11.8652 3.6581,11.8408L5.1077,10.2572C5.1391,10.2228 5.177,10.1955 5.2192,10.1767C5.2614,10.158 5.307,10.1483 5.353,10.1482H12.219C12.2517,10.1482 12.2838,10.158 12.3112,10.1763C12.3385,10.1946 12.3601,10.2207 12.3732,10.2513C12.3862,10.2819 12.3902,10.3158 12.3847,10.3487C12.3791,10.3816 12.3643,10.4122 12.3419,10.4366ZM10.8935,7.2476C10.862,7.2132 10.8239,7.1858 10.7816,7.167C10.7392,7.1483 10.6936,7.1386 10.6474,7.1387H3.7811C3.7483,7.1387 3.7163,7.1484 3.6889,7.1667C3.6615,7.1851 3.6399,7.2111 3.6268,7.2418C3.6138,7.2724 3.6098,7.3063 3.6154,7.3392C3.6209,7.3721 3.6358,7.4026 3.6581,7.4271L5.1077,9.0107C5.1391,9.045 5.177,9.0723 5.2192,9.0911C5.2614,9.1098 5.307,9.1195 5.353,9.1196H12.219C12.2517,9.1196 12.2838,9.1099 12.3112,9.0915C12.3385,9.0732 12.3601,9.0472 12.3732,9.0165C12.3862,8.9859 12.3902,8.952 12.3847,8.9191C12.3791,8.8862 12.3643,8.8557 12.3419,8.8312L10.8935,7.2476ZM3.7811,6.1101H10.6474C10.6936,6.1101 10.7392,6.1005 10.7816,6.0817C10.8239,6.063 10.862,6.0356 10.8935,6.0012L12.3419,4.4175C12.3643,4.3931 12.3791,4.3626 12.3847,4.3296C12.3902,4.2967 12.3862,4.2629 12.3732,4.2323C12.3601,4.2016 12.3385,4.1755 12.3112,4.1572C12.2838,4.1389 12.2517,4.1291 12.219,4.1291H5.353C5.307,4.1292 5.2614,4.1389 5.2192,4.1577C5.177,4.1764 5.1391,4.2038 5.1077,4.2381L3.6585,5.8217C3.6362,5.8461 3.6213,5.8766 3.6157,5.9095C3.6102,5.9424 3.6141,5.9762 3.6272,6.0068C3.6402,6.0374 3.6617,6.0635 3.689,6.0819C3.7163,6.1002 3.7483,6.11 3.7811,6.1101Z">
<aapt:attr name="android:fillColor">
<gradient android:endX="11.7097" android:endY="4.18558"
android:startX="4.35356" android:startY="12.3198" android:type="linear">
<item android:color="#FF9945FF" android:offset="0.08"/>
<item android:color="#FF8752F3" android:offset="0.3"/>
<item android:color="#FF5497D5" android:offset="0.5"/>
<item android:color="#FF43B4CA" android:offset="0.6"/>
<item android:color="#FF28E0B9" android:offset="0.72"/>
<item android:color="#FF19FB9B" android:offset="0.97"/>
</gradient>
</aapt:attr>
</path>
</vector>

View file

@ -0,0 +1,12 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<group>
<clip-path android:pathData="M0,0h16v16h-16z"/>
<path android:fillColor="#F1F1F1" android:pathData="M8,0L8,0A8,8 0,0 1,16 8L16,8A8,8 0,0 1,8 16L8,16A8,8 0,0 1,0 8L0,8A8,8 0,0 1,8 0z"/>
<group>
<clip-path android:pathData="M7.871,2.8386L7.871,2.8386A5.0322,5.0322 0,0 1,12.9032 7.8709L12.9032,7.8709A5.0322,5.0322 0,0 1,7.871 12.9031L7.871,12.9031A5.0322,5.0322 0,0 1,2.8387 7.8709L2.8387,7.8709A5.0322,5.0322 0,0 1,7.871 2.8386z"/>
<path android:fillColor="#A1A1A4" android:pathData="M7.9897,3.6149C7.4207,3.5991 6.8543,3.6974 6.324,3.9042C5.7937,4.111 5.3102,4.4221 4.9022,4.8189C4.4941,5.2158 4.1698,5.6904 3.9483,6.2148C3.7269,6.7392 3.6128,7.3026 3.6129,7.8718C3.6129,7.9804 3.6171,8.0882 3.6254,8.196C3.637,8.3484 3.6031,8.5007 3.5282,8.6339C3.4533,8.7671 3.3406,8.8752 3.2044,8.9445L2.8387,9.1311V10.0009L3.9156,9.4519L4.2646,9.2741L4.6084,9.0993L10.7771,5.9558L11.4703,5.6027L12.9033,4.8726V4.0028L11.4829,4.7275L10.271,5.3452L4.4189,8.326C4.3992,8.175 4.3894,8.0228 4.3895,7.8706C4.3903,7.2632 4.5498,6.6667 4.8521,6.1399C5.1544,5.6132 5.589,5.1746 6.113,4.8675C6.637,4.5605 7.2321,4.3956 7.8393,4.3893C8.4466,4.3829 9.045,4.5354 9.5753,4.8315L10.2689,4.478L10.3725,4.4251C9.678,3.9211 8.8474,3.6388 7.9897,3.6149ZM12.9033,5.7427L4.9586,9.7878L4.2654,10.1418L2.8387,10.8694V11.7383L4.2553,11.0161L5.4673,10.3984L11.3256,7.4139C11.3453,7.5657 11.3551,7.7187 11.355,7.8718C11.3546,8.4798 11.1952,9.0771 10.8926,9.6045C10.59,10.1319 10.1548,10.5709 9.6301,10.8781C9.1054,11.1853 8.5094,11.3498 7.9015,11.3555C7.2935,11.3612 6.6946,11.2078 6.1642,10.9105L6.1219,10.9331L5.37,11.3164C6.0053,11.7776 6.7557,12.0541 7.5383,12.1155C8.3209,12.177 9.1053,12.0208 9.8048,11.6644C10.5042,11.308 11.0915,10.7651 11.5018,10.0958C11.912,9.4265 12.1293,8.6568 12.1296,7.8718C12.1296,7.7628 12.1254,7.6529 12.117,7.5447C12.1055,7.3924 12.1393,7.24 12.2141,7.1069C12.289,6.9737 12.4015,6.8656 12.5376,6.7962L12.9033,6.6095V5.7427Z"/>
</group>
</group>
</vector>

View file

@ -0,0 +1,12 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<group>
<clip-path android:pathData="M0,0h16v16h-16z"/>
<path android:fillColor="#000000" android:pathData="M8,0L8,0A8,8 0,0 1,16 8L16,8A8,8 0,0 1,8 16L8,16A8,8 0,0 1,0 8L0,8A8,8 0,0 1,8 0z"/>
<group>
<clip-path android:pathData="M7.871,2.8386L7.871,2.8386A5.0322,5.0322 0,0 1,12.9032 7.8709L12.9032,7.8709A5.0322,5.0322 0,0 1,7.871 12.9031L7.871,12.9031A5.0322,5.0322 0,0 1,2.8387 7.8709L2.8387,7.8709A5.0322,5.0322 0,0 1,7.871 2.8386z"/>
<path android:fillColor="#ffffff" android:pathData="M7.9897,3.6149C7.4207,3.5991 6.8543,3.6974 6.324,3.9042C5.7937,4.111 5.3102,4.4221 4.9022,4.8189C4.4941,5.2158 4.1698,5.6904 3.9483,6.2148C3.7269,6.7392 3.6128,7.3026 3.6129,7.8718C3.6129,7.9804 3.6171,8.0882 3.6254,8.196C3.637,8.3484 3.6031,8.5007 3.5282,8.6339C3.4533,8.7671 3.3406,8.8752 3.2044,8.9445L2.8387,9.1311V10.0009L3.9156,9.4519L4.2646,9.2741L4.6084,9.0993L10.7771,5.9558L11.4703,5.6027L12.9033,4.8726V4.0028L11.4829,4.7275L10.271,5.3452L4.4189,8.326C4.3992,8.175 4.3894,8.0228 4.3895,7.8706C4.3903,7.2632 4.5498,6.6667 4.8521,6.1399C5.1544,5.6132 5.589,5.1746 6.113,4.8675C6.637,4.5605 7.2321,4.3956 7.8393,4.3893C8.4466,4.3829 9.045,4.5354 9.5753,4.8315L10.2689,4.478L10.3725,4.4251C9.678,3.9211 8.8474,3.6388 7.9897,3.6149ZM12.9033,5.7427L4.9586,9.7878L4.2654,10.1418L2.8387,10.8694V11.7383L4.2553,11.0161L5.4673,10.3984L11.3256,7.4139C11.3453,7.5657 11.3551,7.7187 11.355,7.8718C11.3546,8.4798 11.1952,9.0771 10.8926,9.6045C10.59,10.1319 10.1548,10.5709 9.6301,10.8781C9.1054,11.1853 8.5094,11.3498 7.9015,11.3555C7.2935,11.3612 6.6946,11.2078 6.1642,10.9105L6.1219,10.9331L5.37,11.3164C6.0053,11.7776 6.7557,12.0541 7.5383,12.1155C8.3209,12.177 9.1053,12.0208 9.8048,11.6644C10.5042,11.308 11.0915,10.7651 11.5018,10.0958C11.912,9.4265 12.1293,8.6568 12.1296,7.8718C12.1296,7.7628 12.1254,7.6529 12.117,7.5447C12.1055,7.3924 12.1393,7.24 12.2141,7.1069C12.289,6.9737 12.4015,6.8656 12.5376,6.7962L12.9033,6.6095V5.7427Z"/>
</group>
</group>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#F1F1F1" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#A1A1A4" android:pathData="M8.5216,13C7.8414,13 7.345,12.8281 7.0322,12.4844C6.7425,12.1934 6.5744,11.7939 6.5646,11.3732C6.5611,11.2455 6.5893,11.1189 6.6465,11.006C6.6999,10.9085 6.777,10.8275 6.8699,10.7715C6.9779,10.715 7.097,10.6856 7.2177,10.6856C7.3384,10.6856 7.4574,10.715 7.5654,10.7715C7.6582,10.8273 7.7349,10.9083 7.7875,11.006C7.8464,11.1184 7.8757,11.2451 7.8724,11.3732C7.8784,11.5263 7.8366,11.6772 7.7532,11.8029C7.6838,11.9056 7.5844,11.9818 7.4702,12.0203C7.5819,12.1695 7.74,12.2729 7.917,12.3125C8.1149,12.3728 8.3199,12.4038 8.5261,12.4046C8.799,12.4071 9.0663,12.3233 9.2931,12.164C9.5284,11.9896 9.7038,11.7403 9.7935,11.4531C9.9071,11.1112 9.9626,10.7511 9.9573,10.3891C9.9665,10.0117 9.9058,9.636 9.7786,9.2828C9.6829,9.0003 9.5013,8.7587 9.2618,8.5953C9.0392,8.4475 8.7807,8.3699 8.5173,8.3719C8.2877,8.3923 8.0663,8.4711 7.8724,8.6016L7.3942,8.8531V8.6016L9.5433,5.5769H6.5646V8.7156C6.5562,8.9421 6.6133,9.166 6.7284,9.3578C6.7842,9.4414 6.8595,9.5085 6.9472,9.5525C7.0348,9.5966 7.1319,9.6162 7.2288,9.6093C7.4081,9.6055 7.5814,9.5415 7.7233,9.4265C7.8841,9.3029 8.0241,9.1518 8.1373,8.9796C8.1475,8.9495 8.1663,8.9233 8.1912,8.9047C8.2111,8.8866 8.2366,8.8766 8.263,8.8766C8.3147,8.8815 8.3637,8.9034 8.403,8.939C8.4528,8.9974 8.4798,9.0732 8.4789,9.1515C8.4732,9.2042 8.4642,9.2563 8.4521,9.3078C8.3463,9.5765 8.1689,9.8075 7.9412,9.9732C7.7298,10.1233 7.48,10.2029 7.2247,10.2016C6.5798,10.2016 6.133,10.0682 5.8844,9.8016C5.7566,9.6542 5.6581,9.4815 5.5947,9.2937C5.5312,9.1059 5.5042,8.9067 5.515,8.7078V5.5769H4V4.9937H5.5221V3.664L5.1736,3.2982V3H6.1848L6.5646,3.2063V4.9937L10.4993,4.9812L10.8911,5.3937L8.4784,7.9372C8.6241,7.8757 8.7776,7.8368 8.9341,7.8216C9.2437,7.8358 9.5458,7.9263 9.8159,8.0857C10.1287,8.2417 10.3923,8.4885 10.5755,8.7969C10.7396,9.0579 10.8558,9.3488 10.9181,9.6547C10.9692,9.8959 10.9967,10.142 11,10.3891C11.0016,10.8607 10.8997,11.3264 10.7021,11.75C10.5148,12.1602 10.1995,12.491 9.8085,12.6876C9.4082,12.8945 8.9678,13.0014 8.5216,13Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#2D7DF8" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#ffffff" android:pathData="M8.5216,13C7.8414,13 7.345,12.8281 7.0322,12.4844C6.7425,12.1934 6.5744,11.7939 6.5646,11.3732C6.5611,11.2455 6.5893,11.1189 6.6465,11.006C6.6999,10.9085 6.777,10.8275 6.8699,10.7715C6.9779,10.715 7.097,10.6856 7.2177,10.6856C7.3384,10.6856 7.4574,10.715 7.5654,10.7715C7.6582,10.8273 7.7349,10.9083 7.7875,11.006C7.8464,11.1184 7.8757,11.2451 7.8724,11.3732C7.8784,11.5263 7.8366,11.6772 7.7532,11.8029C7.6838,11.9056 7.5844,11.9818 7.4702,12.0203C7.5819,12.1695 7.74,12.2729 7.917,12.3125C8.1149,12.3728 8.3199,12.4038 8.5261,12.4046C8.799,12.4071 9.0663,12.3233 9.2931,12.164C9.5284,11.9896 9.7038,11.7403 9.7935,11.4531C9.9071,11.1112 9.9626,10.7511 9.9573,10.3891C9.9665,10.0117 9.9058,9.636 9.7786,9.2828C9.6829,9.0003 9.5013,8.7587 9.2618,8.5953C9.0392,8.4475 8.7807,8.3699 8.5173,8.3719C8.2877,8.3923 8.0663,8.4711 7.8724,8.6016L7.3942,8.8531V8.6016L9.5433,5.5769H6.5646V8.7156C6.5562,8.9421 6.6133,9.166 6.7284,9.3578C6.7842,9.4414 6.8595,9.5085 6.9472,9.5525C7.0348,9.5966 7.1319,9.6162 7.2288,9.6093C7.4081,9.6055 7.5814,9.5415 7.7233,9.4265C7.8841,9.3029 8.0241,9.1518 8.1373,8.9796C8.1475,8.9495 8.1663,8.9233 8.1912,8.9047C8.2111,8.8866 8.2366,8.8766 8.263,8.8766C8.3147,8.8815 8.3637,8.9034 8.403,8.939C8.4528,8.9974 8.4798,9.0732 8.4789,9.1515C8.4732,9.2042 8.4642,9.2563 8.4521,9.3078C8.3463,9.5765 8.1689,9.8075 7.9412,9.9732C7.7298,10.1233 7.48,10.2029 7.2247,10.2016C6.5798,10.2016 6.133,10.0682 5.8844,9.8016C5.7566,9.6542 5.6581,9.4815 5.5947,9.2937C5.5312,9.1059 5.5042,8.9067 5.515,8.7078V5.5769H4V4.9937H5.5221V3.664L5.1736,3.2982V3H6.1848L6.5646,3.2063V4.9937L10.4993,4.9812L10.8911,5.3937L8.4784,7.9372C8.6241,7.8757 8.7776,7.8368 8.9341,7.8216C9.2437,7.8358 9.5458,7.9263 9.8159,8.0857C10.1287,8.2417 10.3923,8.4885 10.5755,8.7969C10.7396,9.0579 10.8558,9.3488 10.9181,9.6547C10.9692,9.8959 10.9967,10.142 11,10.3891C11.0016,10.8607 10.8997,11.3264 10.7021,11.75C10.5148,12.1602 10.1995,12.491 9.8085,12.6876C9.4082,12.8945 8.9678,13.0014 8.5216,13Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#A1A1A4" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#F1F1F1" android:pathData="M8,16C3.5815,16 0,12.4185 0,8C0,3.5815 3.5815,0 8,0C12.4185,0 16,3.5815 16,8C16,12.4185 12.4185,16 8,16ZM11.5355,4C11.5352,4 11.5349,4.0001 11.5346,4.0003L9.248,6.2615C8.9152,6.5899 8.4665,6.7741 7.999,6.7741C7.5315,6.7741 7.0827,6.5899 6.75,6.2615L4.6138,4.1472C4.5185,4.0529 4.3898,4 4.2557,4C3.8009,4 3.5743,4.551 3.8976,4.8709L6.0275,6.9785C6.5533,7.4966 7.2618,7.787 8,7.787C8.7382,7.787 9.4467,7.4966 9.9725,6.9785L11.9537,5.0167C12.331,4.6431 12.0664,4 11.5355,4ZM4.4475,12.2811C4.4475,12.2813 4.4477,12.2813 4.4478,12.2813L6.752,10C7.0848,9.6716 7.5335,9.4874 8.001,9.4874C8.4685,9.4874 8.9172,9.6716 9.25,10L11.4037,12.134C11.499,12.2285 11.6278,12.2815 11.762,12.2815C12.2168,12.2815 12.4433,11.7305 12.1201,11.4106L9.9725,9.285C9.4467,8.7669 8.7382,8.4765 8,8.4765C7.2618,8.4765 6.5533,8.7669 6.0275,9.285L3.7291,11.5595C3.4613,11.8245 3.649,12.281 4.0258,12.281H4.4474C4.4474,12.281 4.4475,12.2811 4.4475,12.2811Z"/>
</vector>

View file

@ -0,0 +1,6 @@
<vector android:autoMirrored="true" android:height="16dp"
android:viewportHeight="16" android:viewportWidth="16"
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#ffffff" android:pathData="M8,8m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
<path android:fillColor="#000000" android:pathData="M8,16C3.5815,16 0,12.4185 0,8C0,3.5815 3.5815,0 8,0C12.4185,0 16,3.5815 16,8C16,12.4185 12.4185,16 8,16ZM11.5355,4C11.5352,4 11.5349,4.0001 11.5346,4.0003L9.248,6.2615C8.9152,6.5899 8.4665,6.7741 7.999,6.7741C7.5315,6.7741 7.0827,6.5899 6.75,6.2615L4.6138,4.1472C4.5185,4.0529 4.3898,4 4.2557,4C3.8009,4 3.5743,4.551 3.8976,4.8709L6.0275,6.9785C6.5533,7.4966 7.2618,7.787 8,7.787C8.7382,7.787 9.4467,7.4966 9.9725,6.9785L11.9537,5.0167C12.331,4.6431 12.0664,4 11.5355,4ZM4.4475,12.2811C4.4475,12.2813 4.4477,12.2813 4.4478,12.2813L6.752,10C7.0848,9.6716 7.5335,9.4874 8.001,9.4874C8.4685,9.4874 8.9172,9.6716 9.25,10L11.4037,12.134C11.499,12.2285 11.6278,12.2815 11.762,12.2815C12.2168,12.2815 12.4433,11.7305 12.1201,11.4106L9.9725,9.285C9.4467,8.7669 8.7382,8.4765 8,8.4765C7.2618,8.4765 6.5533,8.7669 6.0275,9.285L3.7291,11.5595C3.4613,11.8245 3.649,12.281 4.0258,12.281H4.4474C4.4474,12.281 4.4475,12.2811 4.4475,12.2811Z"/>
</vector>

View file

@ -25,39 +25,12 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_details_confirm" <androidx.compose.ui.platform.ComposeView
android:id="@+id/cv_currencies"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@android:color/white" app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_popular_tokens"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clipToPadding="false"
android:paddingBottom="80dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_tokens_save_changes"
style="@style/TapBlackButton"
android:layout_width="204dp"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:enabled="false"
android:gravity="center"
android:text="@string/common_save_changes"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View file

@ -35,4 +35,7 @@
<string name="search_tokens_title">Search tokens</string> <string name="search_tokens_title">Search tokens</string>
<string name="alert_demo_message">You are currently running in Demo mode. All funds are not real.</string> <string name="alert_demo_message">You are currently running in Demo mode. All funds are not real.</string>
<string name="alert_demo_feature_disabled">This feature is disabled in Demo mode</string> <string name="alert_demo_feature_disabled">This feature is disabled in Demo mode</string>
<string name="currency_subtitle_expanded">Available networks</string>
</resources> </resources>

View file

@ -35,4 +35,6 @@
<string name="search_tokens_title">Search tokens</string> <string name="search_tokens_title">Search tokens</string>
<string name="alert_demo_message">You are currently running in Demo mode. All funds are not real.</string> <string name="alert_demo_message">You are currently running in Demo mode. All funds are not real.</string>
<string name="alert_demo_feature_disabled">This feature is disabled in Demo mode</string> <string name="alert_demo_feature_disabled">This feature is disabled in Demo mode</string>
<string name="currency_subtitle_expanded">Available networks</string>
</resources> </resources>

View file

@ -35,4 +35,7 @@
<string name="search_tokens_title">Search tokens</string> <string name="search_tokens_title">Search tokens</string>
<string name="alert_demo_message">You are currently running in Demo mode. All funds are not real.</string> <string name="alert_demo_message">You are currently running in Demo mode. All funds are not real.</string>
<string name="alert_demo_feature_disabled">This feature is disabled in Demo mode</string> <string name="alert_demo_feature_disabled">This feature is disabled in Demo mode</string>
<string name="currency_subtitle_expanded">Available networks</string>
</resources> </resources>

View file

@ -35,4 +35,6 @@
<string name="search_tokens_title">Поиск токенов</string> <string name="search_tokens_title">Поиск токенов</string>
<string name="alert_demo_message">Приложение работает в демонстрационном режиме. Средства на всех счетах ненастоящие.</string> <string name="alert_demo_message">Приложение работает в демонстрационном режиме. Средства на всех счетах ненастоящие.</string>
<string name="alert_demo_feature_disabled">Эта функция недоступна в демонстрационном режиме</string> <string name="alert_demo_feature_disabled">Эта функция недоступна в демонстрационном режиме</string>
<string name="currency_subtitle_expanded">Доступные сети</string>
</resources> </resources>

View file

@ -35,4 +35,6 @@
<string name="search_tokens_title">Search tokens</string> <string name="search_tokens_title">Search tokens</string>
<string name="alert_demo_message">You are currently running in Demo mode. All funds are not real.</string> <string name="alert_demo_message">You are currently running in Demo mode. All funds are not real.</string>
<string name="alert_demo_feature_disabled">This feature is disabled in Demo mode</string> <string name="alert_demo_feature_disabled">This feature is disabled in Demo mode</string>
<string name="currency_subtitle_expanded">Available networks</string>
</resources> </resources>