Updated on 2026-08-14
This commit is contained in:
commit
fb3d9cd2d6
20 changed files with 220 additions and 181 deletions
|
|
@ -157,22 +157,22 @@ class TapWalletManager {
|
|||
private fun loadMultiWalletData(
|
||||
card: Card, primaryBlockchain: Blockchain?, primaryWalletManager: WalletManager?
|
||||
) {
|
||||
val primaryTokens = primaryWalletManager?.cardTokens ?: emptySet()
|
||||
val primaryTokens = primaryWalletManager?.cardTokens?.toList() ?: emptyList()
|
||||
val savedCurrencies = currenciesRepository.loadCardCurrencies(card.cardId)
|
||||
|
||||
if (savedCurrencies == null) {
|
||||
if (primaryBlockchain != null && primaryWalletManager != null) {
|
||||
store.dispatch(WalletAction.MultiWallet.SaveCurrencies(
|
||||
CardCurrencies(
|
||||
blockchains = setOf(primaryBlockchain), tokens = primaryTokens
|
||||
blockchains = listOf(primaryBlockchain), tokens = primaryTokens
|
||||
)))
|
||||
store.dispatch(WalletAction.MultiWallet.AddWalletManagers(primaryWalletManager))
|
||||
store.dispatch(WalletAction.MultiWallet.AddBlockchains(listOf(primaryBlockchain)))
|
||||
store.dispatch(WalletAction.MultiWallet.AddTokens(primaryTokens.toList()))
|
||||
} else {
|
||||
val blockchains = setOf(Blockchain.Bitcoin, Blockchain.Ethereum)
|
||||
val blockchains = listOf(Blockchain.Bitcoin, Blockchain.Ethereum)
|
||||
store.dispatch(WalletAction.MultiWallet.SaveCurrencies(
|
||||
CardCurrencies(blockchains = blockchains, tokens = emptySet())
|
||||
CardCurrencies(blockchains = blockchains, tokens = emptyList())
|
||||
))
|
||||
val walletManagers =
|
||||
walletManagerFactory.makeWalletManagersForApp(card, blockchains.toList())
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@ import com.tangem.tap.network.createMoshi
|
|||
|
||||
class CurrenciesRepository(val context: Application) {
|
||||
private val moshi = createMoshi()
|
||||
private val blockchainsAdapter: JsonAdapter<Set<Blockchain>> = moshi.adapter(
|
||||
Types.newParameterizedType(Set::class.java, Blockchain::class.java)
|
||||
private val blockchainsAdapter: JsonAdapter<List<Blockchain>> = moshi.adapter(
|
||||
Types.newParameterizedType(List::class.java, Blockchain::class.java)
|
||||
)
|
||||
private val tokensAdapter: JsonAdapter<Set<TokenDao>> = moshi.adapter(
|
||||
Types.newParameterizedType(Set::class.java, TokenDao::class.java)
|
||||
private val tokensAdapter: JsonAdapter<List<TokenDao>> = moshi.adapter(
|
||||
Types.newParameterizedType(List::class.java, TokenDao::class.java)
|
||||
)
|
||||
private val obsoleteTokensAdapter: JsonAdapter<Set<ObsoleteTokenDao>> = moshi.adapter(
|
||||
Types.newParameterizedType(Set::class.java, ObsoleteTokenDao::class.java)
|
||||
private val obsoleteTokensAdapter: JsonAdapter<List<ObsoleteTokenDao>> = moshi.adapter(
|
||||
Types.newParameterizedType(List::class.java, ObsoleteTokenDao::class.java)
|
||||
)
|
||||
|
||||
fun loadCardCurrencies(cardId: String): CardCurrencies? {
|
||||
|
|
@ -51,48 +51,48 @@ class CurrenciesRepository(val context: Application) {
|
|||
}
|
||||
|
||||
fun removeToken(cardId: String, token: Token) {
|
||||
val tokens = loadSavedTokens(cardId).filterNot { it == token }.toSet()
|
||||
val tokens = loadSavedTokens(cardId).filterNot { it == token }
|
||||
saveTokens(cardId, tokens)
|
||||
}
|
||||
|
||||
fun removeBlockchain(cardId: String, blockchain: Blockchain) {
|
||||
val blockchains = loadSavedBlockchains(cardId).filterNot { it == blockchain }.toSet()
|
||||
val blockchains = loadSavedBlockchains(cardId).filterNot { it == blockchain }
|
||||
saveBlockchains(cardId, blockchains)
|
||||
}
|
||||
|
||||
private fun loadSavedTokens(cardId: String): Set<Token> {
|
||||
private fun loadSavedTokens(cardId: String): List<Token> {
|
||||
val json = try {
|
||||
context.readFileText(getFileNameForTokens(cardId))
|
||||
} catch (exception: Exception) {
|
||||
return emptySet()
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return try {
|
||||
tokensAdapter.fromJson(json)!!.map { it.toToken() }.toSet()
|
||||
tokensAdapter.fromJson(json)!!.map { it.toToken() }
|
||||
} catch (exception: Exception) {
|
||||
try {
|
||||
obsoleteTokensAdapter.fromJson(json)!!.map { it.toToken() }.toSet()
|
||||
obsoleteTokensAdapter.fromJson(json)!!.map { it.toToken() }
|
||||
} catch (exception: Exception) {
|
||||
emptySet()
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveTokens(cardId: String, tokens: Set<Token>) {
|
||||
val json = tokensAdapter.toJson(tokens.map { TokenDao.fromToken(it) }.toSet())
|
||||
private fun saveTokens(cardId: String, tokens: List<Token>) {
|
||||
val json = tokensAdapter.toJson(tokens.map { TokenDao.fromToken(it) }.distinct())
|
||||
context.rewriteFile(json, getFileNameForTokens(cardId))
|
||||
}
|
||||
|
||||
private fun loadSavedBlockchains(cardId: String): Set<Blockchain> {
|
||||
private fun loadSavedBlockchains(cardId: String): List<Blockchain> {
|
||||
return try {
|
||||
val json = context.readFileText(getFileNameForBlockchains(cardId))
|
||||
blockchainsAdapter.fromJson(json) ?: emptySet()
|
||||
blockchainsAdapter.fromJson(json) ?: emptyList()
|
||||
} catch (exception: Exception) {
|
||||
emptySet()
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveBlockchains(cardId: String, blockchains: Set<Blockchain>) {
|
||||
private fun saveBlockchains(cardId: String, blockchains: List<Blockchain>) {
|
||||
val json = blockchainsAdapter.toJson(blockchains)
|
||||
context.rewriteFile(json, getFileNameForBlockchains(cardId))
|
||||
}
|
||||
|
|
@ -224,12 +224,12 @@ data class ObsoleteTokenDao(
|
|||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class CardCurrenciesDao(
|
||||
val tokens: Set<TokenDao>,
|
||||
val blockchains: Set<Blockchain>,
|
||||
val tokens: List<TokenDao>,
|
||||
val blockchains: List<Blockchain>,
|
||||
) {
|
||||
fun toCardCurrencies(): CardCurrencies {
|
||||
return CardCurrencies(
|
||||
tokens = tokens.map { it.toToken() }.toSet(),
|
||||
tokens = tokens.map { it.toToken() }.distinct(),
|
||||
blockchains = blockchains
|
||||
)
|
||||
}
|
||||
|
|
@ -237,7 +237,7 @@ data class CardCurrenciesDao(
|
|||
companion object {
|
||||
fun fromCardCurrencies(cardCurrencies: CardCurrencies): CardCurrenciesDao {
|
||||
return CardCurrenciesDao(
|
||||
tokens = cardCurrencies.tokens.map { TokenDao.fromToken(it) }.toSet(),
|
||||
tokens = cardCurrencies.tokens.map { TokenDao.fromToken(it) }.distinct(),
|
||||
blockchains = cardCurrencies.blockchains
|
||||
)
|
||||
}
|
||||
|
|
@ -245,6 +245,6 @@ data class CardCurrenciesDao(
|
|||
}
|
||||
|
||||
data class CardCurrencies(
|
||||
val tokens: Set<Token>,
|
||||
val blockchains: Set<Blockchain>,
|
||||
val tokens: List<Token>,
|
||||
val blockchains: List<Blockchain>,
|
||||
)
|
||||
|
|
@ -10,6 +10,7 @@ import com.tangem.tap.common.extensions.show
|
|||
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.domain.isMultiwalletAllowed
|
||||
import com.tangem.tap.domain.twins.getTwinCardIdForUser
|
||||
import com.tangem.tap.features.details.redux.DetailsAction
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
|
|
@ -112,6 +113,7 @@ class DetailsFragment : Fragment(R.layout.fragment_details), StoreSubscriber<Det
|
|||
store.dispatch(GlobalAction.SendFeedback(FeedbackEmail()))
|
||||
}
|
||||
|
||||
tv_wallet_connect.show(state.card?.isMultiwalletAllowed == true)
|
||||
tv_wallet_connect.setOnClickListener {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.WalletConnectSessions))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,9 +68,9 @@ class AmountMiddleware {
|
|||
} else {
|
||||
val amountErrors = extractErrorsForAmountField(transactionErrors)
|
||||
if (amountErrors.isNotEmpty()) {
|
||||
transactionErrors.removeAll(amountErrors)
|
||||
dispatch(AmountAction.SetAmountError(createValidateTransactionError(amountErrors, walletManager)))
|
||||
}
|
||||
transactionErrors.removeAll(amountErrors)
|
||||
if (transactionErrors.isNotEmpty()) {
|
||||
dispatch(SendAction.SendError(createValidateTransactionError(transactionErrors, walletManager)))
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ class AmountMiddleware {
|
|||
|
||||
dispatch(AmountAction.SetAmount(sendState.amountState.balanceCrypto, false))
|
||||
if (sendState.amountState.isCoinAmount()) {
|
||||
dispatch(FeeAction.ChangeLayoutVisibility(main = true, controls = true, chipGroup = true))
|
||||
dispatch(FeeAction.ChangeLayoutVisibility(main = true, controls = true))
|
||||
dispatch(FeeActionUi.ChangeIncludeFee(true))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class RequestFeeMiddleware {
|
|||
|
||||
if (!SendState.isReadyToRequestFee()) {
|
||||
dispatch(FeeAction.FeeCalculation.SetFeeError(FeeAction.Error.ADDRESS_OR_AMOUNT_IS_EMPTY))
|
||||
dispatch(FeeAction.ChangeLayoutVisibility(main = false, chipGroup = true))
|
||||
// dispatch(FeeAction.ChangeLayoutVisibility(main = false, chipGroup = true))
|
||||
dispatch(ReceiptAction.RefreshReceipt)
|
||||
dispatch(SendAction.ChangeSendButtonState(sendState.getButtonState()))
|
||||
return
|
||||
|
|
@ -60,7 +60,7 @@ class RequestFeeMiddleware {
|
|||
}
|
||||
is Result.Failure -> {
|
||||
dispatch(FeeAction.FeeCalculation.SetFeeError(FeeAction.Error.REQUEST_FAILED))
|
||||
dispatch(FeeAction.ChangeLayoutVisibility(main = false, controls = false, chipGroup = false))
|
||||
dispatch(FeeAction.ChangeLayoutVisibility(main = false))
|
||||
}
|
||||
}
|
||||
dispatch(AmountActionUi.CheckAmountToSend)
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ fun extractErrorsForAmountField(errors: EnumSet<TransactionError>): EnumSet<Tran
|
|||
showIntoAmountField.add(it)
|
||||
}
|
||||
TransactionError.TotalExceedsBalance -> {
|
||||
val notAcceptable = listOf(TransactionError.FeeExceedsBalance, TransactionError.FeeExceedsBalance)
|
||||
val notAcceptable = listOf(TransactionError.AmountExceedsBalance, TransactionError.FeeExceedsBalance)
|
||||
if (!showIntoAmountField.containsAll(notAcceptable)) showIntoAmountField.add(it)
|
||||
}
|
||||
TransactionError.InvalidAmountValue -> showIntoAmountField.add(it)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class FeeReducer : SendInternalReducer {
|
|||
state.copy(
|
||||
mainLayoutIsVisible = getVisibility(state.mainLayoutIsVisible, action.main),
|
||||
controlsLayoutIsVisible = getVisibility(state.controlsLayoutIsVisible, action.controls),
|
||||
feeChipGroupIsVisible = getVisibility(state.mainLayoutIsVisible, action.chipGroup)
|
||||
feeChipGroupIsVisible = getVisibility(state.feeChipGroupIsVisible, action.chipGroup)
|
||||
)
|
||||
}
|
||||
is FeeAction.FeeCalculation.SetFeeResult -> {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ private fun internalReduce(action: Action, state: AppState): TokensState {
|
|||
}
|
||||
|
||||
private fun List<WalletData>.toCardCurrencies(): CardCurrencies {
|
||||
val tokens = mapNotNull { (it.currency as? Currency.Token)?.token }.toSet()
|
||||
val blockchains = mapNotNull { (it.currency as? Currency.Blockchain)?.blockchain }.toSet()
|
||||
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)
|
||||
}
|
||||
|
|
@ -132,12 +132,31 @@ data class WalletState(
|
|||
|
||||
fun replaceWalletInWallets(walletData: WalletData?): List<WalletData> {
|
||||
if (walletData == null) return wallets
|
||||
return wallets.filter { it.currencyData.currency != walletData.currencyData.currency } + walletData
|
||||
var changed = false
|
||||
val updatedWallets = wallets.map {
|
||||
if (it.currencyData.currency == walletData.currencyData.currency) {
|
||||
changed = true
|
||||
walletData
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
return if (changed) updatedWallets else wallets + walletData
|
||||
}
|
||||
|
||||
fun replaceSomeWallets(newWallets: List<WalletData>): List<WalletData> {
|
||||
val currencies = newWallets.map { it.currencyData.currency }
|
||||
return wallets.filter { !currencies.contains(it.currencyData.currency) } + newWallets
|
||||
val remainingWallets: MutableList<WalletData> = newWallets.toMutableList()
|
||||
val updatedWallets = wallets.map { wallet ->
|
||||
val newWallet = newWallets
|
||||
.firstOrNull { wallet.currencyData.currency == it.currencyData.currency }
|
||||
if (newWallet == null) {
|
||||
wallet
|
||||
} else {
|
||||
remainingWallets.remove(newWallet)
|
||||
newWallet
|
||||
}
|
||||
}
|
||||
return updatedWallets + remainingWallets
|
||||
}
|
||||
|
||||
fun addWalletManagers(newWalletManagers: List<WalletManager>): WalletState {
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
|
|||
|
||||
btn_share.setOnClickListener { store.dispatch(WalletAction.ShowDialog.QrCode) }
|
||||
|
||||
btn_top_up.setOnClickListener { store.dispatch(WalletAction.TradeCryptoAction.Buy) }
|
||||
btn_trade.setOnClickListener { store.dispatch(WalletAction.TradeCryptoAction.Buy) }
|
||||
|
||||
btn_sell.setOnClickListener { store.dispatch(WalletAction.TradeCryptoAction.Sell) }
|
||||
}
|
||||
|
|
@ -138,7 +138,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
|
|||
srl_wallet_details.isRefreshing = false
|
||||
}
|
||||
|
||||
btn_top_up.isEnabled = selectedWallet.tradeCryptoState.buyingAllowed
|
||||
btn_trade.isEnabled = selectedWallet.tradeCryptoState.buyingAllowed
|
||||
btn_sell.show(selectedWallet.tradeCryptoState.sellingAllowed)
|
||||
}
|
||||
|
||||
|
|
@ -286,7 +286,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
|
|||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.meny_remove -> {
|
||||
R.id.menu_remove -> {
|
||||
store.state.walletState.getSelectedWalletData()?.let { walletData ->
|
||||
store.dispatch(WalletAction.MultiWallet.RemoveWallet(walletData))
|
||||
store.dispatch(WalletAction.MultiWallet.SelectWallet(null))
|
||||
|
|
@ -300,9 +300,11 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
|
|||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
if (store.state.walletState.canBeRemoved(store.state.walletState.getSelectedWalletData())) {
|
||||
inflater.inflate(R.menu.wallet_details, menu)
|
||||
}
|
||||
inflater.inflate(R.menu.wallet_details, menu)
|
||||
val walletCanBeRemoved = store.state.walletState.canBeRemoved(
|
||||
store.state.walletState.getSelectedWalletData()
|
||||
)
|
||||
menu.getItem(0).isEnabled = walletCanBeRemoved
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import com.tangem.tap.features.wallet.ui.BalanceStatus
|
|||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.item_currency_wallet.view.*
|
||||
import java.math.BigDecimal
|
||||
|
||||
class WalletAdapter
|
||||
: ListAdapter<WalletData, WalletAdapter.WalletsViewHolder>(DiffUtilCallback) {
|
||||
|
|
@ -28,36 +27,8 @@ class WalletAdapter
|
|||
}
|
||||
|
||||
fun submitList(list: List<WalletData>, primaryBlockchain: Blockchain?, primaryToken: Token? = null) {
|
||||
val listModified = list.toMutableList()
|
||||
val primaryBlockchainWallet = when (
|
||||
val index = listModified.indexOfFirst {
|
||||
(it.currency as? Currency.Blockchain)?.blockchain == primaryBlockchain
|
||||
}
|
||||
) {
|
||||
-1 -> null
|
||||
else -> listModified.removeAt(index)
|
||||
}
|
||||
|
||||
|
||||
val primaryTokenWallet = if (primaryToken == null) null else when (
|
||||
val index = listModified.indexOfFirst { (it.currency as? Currency.Token)?.token == primaryToken }
|
||||
) {
|
||||
-1 -> null
|
||||
else -> listModified.removeAt(index)
|
||||
}
|
||||
|
||||
if (list.all { it.currencyData.fiatAmountFormatted == null }) {
|
||||
val sortedList = listOfNotNull(primaryBlockchainWallet, primaryTokenWallet) + listModified
|
||||
super.submitList(sortedList)
|
||||
return
|
||||
}
|
||||
|
||||
val sorted = listModified.sortedWith(
|
||||
compareByDescending<WalletData> { it.currencyData.fiatAmount ?: BigDecimal.ZERO }
|
||||
.thenBy { it.currencyData.currency }
|
||||
)
|
||||
val sortedList = listOfNotNull(primaryBlockchainWallet, primaryTokenWallet) + sorted
|
||||
super.submitList(sortedList)
|
||||
// We used this method to sort the list of currencies. Sorting is disabled for now.
|
||||
super.submitList(list)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WalletsViewHolder {
|
||||
|
|
|
|||
|
|
@ -142,12 +142,10 @@ class SingleWalletView : WalletView {
|
|||
}
|
||||
btn_show_qr.setOnClickListener { store.dispatch(WalletAction.ShowDialog.QrCode) }
|
||||
|
||||
btn_top_up.setOnClickListener {
|
||||
tradeCryptoAction(state.tradeCryptoState)
|
||||
}
|
||||
setupTradeButton(fragment, state.tradeCryptoState)
|
||||
}
|
||||
|
||||
private fun tradeCryptoAction(tradeCryptoState: TradeCryptoState) {
|
||||
private fun setupTradeButton(fragment: WalletFragment, tradeCryptoState: TradeCryptoState) {
|
||||
val allowedToBuy = tradeCryptoState.buyingAllowed
|
||||
val allowedToSell = tradeCryptoState.sellingAllowed
|
||||
val action = when {
|
||||
|
|
@ -156,7 +154,23 @@ class SingleWalletView : WalletView {
|
|||
allowedToBuy && allowedToSell -> WalletAction.ShowDialog.ChooseTradeActionDialog
|
||||
else -> null
|
||||
}
|
||||
if (action != null) store.dispatch(action)
|
||||
val text = when {
|
||||
allowedToBuy && !allowedToSell -> R.string.wallet_button_buy
|
||||
!allowedToBuy && allowedToSell -> R.string.wallet_button_sell
|
||||
allowedToBuy && allowedToSell -> R.string.wallet_button_trade
|
||||
else -> R.string.wallet_button_trade
|
||||
}
|
||||
val icon = when {
|
||||
allowedToBuy && !allowedToSell -> R.drawable.ic_arrow_up_short_btn
|
||||
!allowedToBuy && allowedToSell -> R.drawable.ic_arrow_down_short_button
|
||||
allowedToBuy && allowedToSell -> R.drawable.ic_arrows_up_down_short_btn
|
||||
else -> R.string.wallet_button_trade
|
||||
}
|
||||
with(fragment) {
|
||||
btn_trade.text = getText(text)
|
||||
btn_trade.setCompoundDrawablesWithIntrinsicBounds(0, icon, 0, 0)
|
||||
btn_trade.setOnClickListener { if (action != null) store.dispatch(action) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupButtonsType(state: WalletData, fragment: WalletFragment) = with(fragment) {
|
||||
|
|
|
|||
5
app/src/main/res/color/menu_item_color.xml
Normal file
5
app/src/main/res/color/menu_item_color.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_enabled="true" android:alpha="@dimen/material_emphasis_medium" android:color="?attr/colorOnSurface"/>
|
||||
<item android:alpha="@dimen/material_emphasis_disabled" android:color="?attr/colorOnSurface"/>
|
||||
</selector>
|
||||
12
app/src/main/res/drawable/ic_arrow_down_short_button.xml
Normal file
12
app/src/main/res/drawable/ic_arrow_down_short_button.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="20dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="20">
|
||||
<group>
|
||||
<path
|
||||
android:pathData="M5.853,11.6645L9.7814,8.075C10.0495,7.8439 10.0734,7.3871 9.84,7.1191C9.6067,6.8511 9.1615,6.824 8.9084,7.0724L6.0712,9.6665L6.0712,0.8398C6.0712,0.468 5.7781,0.1667 5.4165,0.1667C5.0549,0.1667 4.7618,0.468 4.7618,0.8398L4.7618,9.6665L1.9246,7.0724C1.6715,6.824 1.2271,6.8576 0.9937,7.1256C0.7604,7.3936 0.7835,7.8439 1.0516,8.075L4.98,11.6645C5.2976,11.8989 5.5827,11.8802 5.853,11.6645L5.853,11.6645Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</group>
|
||||
</vector>
|
||||
|
|
@ -43,27 +43,46 @@
|
|||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="33dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_card_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="4dp"
|
||||
android:text="@string/details_section_title_card"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="@color/colorSecondary"
|
||||
android:textSize="13sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/separatorGrey2"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_card_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_card_id_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingBottom="7dp"
|
||||
android:text="@string/details_row_title_cid"
|
||||
android:textColor="@color/darkGray6"
|
||||
android:textSize="16sp"
|
||||
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_card_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_card_id"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingBottom="7dp"
|
||||
android:textColor="@color/darkGray1"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_card_title"
|
||||
tools:text="0000 0000 0000 0000" />
|
||||
|
||||
<TextView
|
||||
|
|
@ -115,33 +134,47 @@
|
|||
tools:text="48 hashes" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_disclaimer"
|
||||
android:id="@+id/tv_security"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="15dp"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingBottom="7dp"
|
||||
android:textColor="@color/darkGray1"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_angle_bracket_right"
|
||||
app:drawableTint="@color/darkGray1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_signed_hashes_title"
|
||||
tools:text="Long Tap" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_security_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingBottom="7dp"
|
||||
android:text="@string/details_row_title_manage_security"
|
||||
android:textColor="@color/darkGray6"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_signed_hashes" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_erase_wallet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="15dp"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingBottom="7dp"
|
||||
android:text="@string/disclaimer_title"
|
||||
android:text="@string/details_row_title_erase_wallet"
|
||||
android:textColor="@color/darkGray6"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_angle_bracket_right"
|
||||
app:drawableTint="@color/darkGray1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_signed_hashes_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_card_tou"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="15dp"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:text="@string/details_row_title_card_tou"
|
||||
android:textColor="@color/darkGray6"
|
||||
android:textSize="16sp"
|
||||
android:visibility="gone"
|
||||
app:drawableEndCompat="@drawable/ic_angle_bracket_right"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_disclaimer" />
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_security_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_settings_title"
|
||||
|
|
@ -149,12 +182,12 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="22dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:text="@string/details_section_title_settings"
|
||||
android:text="@string/details_section_title_app"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="@color/colorSecondary"
|
||||
android:textSize="13sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_card_tou" />
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_erase_wallet" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -162,6 +195,7 @@
|
|||
android:background="@color/separatorGrey2"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_settings_title" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_app_currency"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
@ -171,6 +205,7 @@
|
|||
android:textColor="@color/darkGray1"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_angle_bracket_right"
|
||||
app:drawableTint="@color/darkGray1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_settings_title"
|
||||
tools:text="USD" />
|
||||
|
|
@ -187,6 +222,37 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_settings_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_disclaimer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="15dp"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingBottom="7dp"
|
||||
android:text="@string/disclaimer_title"
|
||||
android:textColor="@color/darkGray6"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_angle_bracket_right"
|
||||
app:drawableTint="@color/darkGray1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_app_currency_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_card_tou"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="15dp"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:text="@string/details_row_title_card_tou"
|
||||
android:textColor="@color/darkGray6"
|
||||
android:textSize="16sp"
|
||||
android:visibility="gone"
|
||||
app:drawableEndCompat="@drawable/ic_angle_bracket_right"
|
||||
app:drawableTint="@color/darkGray1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_disclaimer" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_send_feedback"
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -197,8 +263,9 @@
|
|||
android:textColor="@color/darkGray6"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_angle_bracket_right"
|
||||
app:drawableTint="@color/darkGray1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_app_currency_title" />
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_card_tou" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_wallet_connect"
|
||||
|
|
@ -210,76 +277,10 @@
|
|||
android:textColor="@color/darkGray6"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_angle_bracket_right"
|
||||
app:drawableTint="@color/darkGray1"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_send_feedback" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/barrier"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="bottom"
|
||||
app:constraint_referenced_ids="tv_wallet_connect,tv_send_feedback" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_card_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="22dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:text="@string/details_section_title_card"
|
||||
android:textAllCaps="true"
|
||||
android:textColor="@color/colorSecondary"
|
||||
android:textSize="13sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/barrier" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/separatorGrey2"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_card_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_security"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="15dp"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingBottom="7dp"
|
||||
android:textColor="@color/darkGray1"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_angle_bracket_right"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_card_title"
|
||||
tools:text="Long Tap" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_security_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingBottom="7dp"
|
||||
android:text="@string/details_row_title_manage_security"
|
||||
android:textColor="@color/darkGray6"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_card_title" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_erase_wallet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawablePadding="15dp"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingBottom="7dp"
|
||||
android:text="@string/details_row_title_erase_wallet"
|
||||
android:textColor="@color/darkGray6"
|
||||
android:textSize="16sp"
|
||||
app:drawableEndCompat="@drawable/ic_angle_bracket_right"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_security_title" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
android:layout_height="?attr/actionBarSize"
|
||||
app:menu="@menu/wallet_details"
|
||||
app:navigationIcon="@drawable/ic_baseline_arrow_back_24"
|
||||
android:theme="@style/ThemeOverlay.MyTheme.Toolbar"
|
||||
app:title=" " />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
|
@ -131,7 +132,7 @@
|
|||
app:constraint_referenced_ids="l_wallet_details,card_pending_transaction_warning" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_top_up"
|
||||
android:id="@+id/btn_trade"
|
||||
style="@style/TapButtonWithIcon"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginStart="16dp"
|
||||
|
|
@ -151,7 +152,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="end"
|
||||
app:constraint_referenced_ids="btn_top_up, btn_sell" />
|
||||
app:constraint_referenced_ids="btn_trade, btn_sell" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/barrier_right_button"
|
||||
|
|
@ -172,7 +173,7 @@
|
|||
app:icon="@drawable/ic_arrow_down"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toEndOf="@id/btn_top_up"
|
||||
app:layout_constraintStart_toEndOf="@id/btn_trade"
|
||||
app:layout_constraintEnd_toStartOf="@id/btn_confirm"
|
||||
app:layout_constraintTop_toBottomOf="@id/barrier"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
android:id="@+id/btn_scan_short"
|
||||
style="@style/TapBlackButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="52dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginBottom="33dp"
|
||||
|
|
@ -17,14 +18,15 @@
|
|||
android:paddingTop="7dp"
|
||||
android:text="@string/wallet_button_scan"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/btn_top_up"
|
||||
app:layout_constraintEnd_toStartOf="@id/btn_trade"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_top_up"
|
||||
android:id="@+id/btn_trade"
|
||||
style="@style/TapButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="52dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginBottom="33dp"
|
||||
|
|
@ -42,6 +44,7 @@
|
|||
android:id="@+id/btn_confirm_short"
|
||||
style="@style/TapButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="52dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
|
|
@ -52,7 +55,7 @@
|
|||
android:text="@string/wallet_button_send"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/btn_top_up"
|
||||
app:layout_constraintStart_toEndOf="@+id/btn_trade"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/meny_remove"
|
||||
android:title="@string/common_remove"
|
||||
android:id="@+id/menu_remove"
|
||||
android:title="@string/remove_token"
|
||||
app:showAsAction="always" />
|
||||
</menu>
|
||||
|
|
@ -89,6 +89,7 @@
|
|||
<string name="custom_token_name_input_placeholder" translatable="false">ex. USD Coin</string>
|
||||
<string name="custom_token_token_symbol_input_placeholder" translatable="false">ex. USDC</string>
|
||||
<string name="add_token_added" translatable="false">Added</string>
|
||||
<string name="remove_token" translatable="false">Remove token</string>
|
||||
|
||||
//Details
|
||||
<string name="details_section_title_blockchain" translatable="false">Blockchain</string>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,14 @@
|
|||
<item name="actionMenuTextColor">@android:color/white</item>
|
||||
</style>
|
||||
|
||||
<!-- Toolbar - overrides the menu text color to use a selector that responds to whether it's enabled or not -->
|
||||
<style name="ThemeOverlay.MyTheme.Toolbar" parent="ThemeOverlay.MaterialComponents.Toolbar.Surface">
|
||||
<!-- Color used in the icons of menu actions (i.e. non-overflow menu items). This is just convention, this will affect anything that uses ?attr/colorControlNormal) -->
|
||||
<item name="colorControlNormal">@color/menu_item_color</item>
|
||||
<!-- Color used in the text of menu actions (i.e. non-overflow menu items) -->
|
||||
<item name="actionMenuTextColor">@color/menu_item_color</item>
|
||||
</style>
|
||||
|
||||
<!-- EditText -->
|
||||
<style name="StyledEditText" parent="TextAppearance.MaterialComponents.Body1">
|
||||
<item name="colorControlNormal">#e34b1c</item>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue