Updated on 2026-08-14

This commit is contained in:
Tangem 2022-04-14 09:51:32 +04:00
parent 74a8eec94b
commit 14d54f0cd1
14 changed files with 103 additions and 49 deletions

View file

@ -79,7 +79,7 @@ dependencies {
implementation 'com.google.android.play:core-ktx:1.8.1'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
implementation 'com.tangem:blockchain:develop-70'
implementation 'com.tangem:blockchain:develop-71'
implementation 'com.tangem.tangem-sdk-kotlin:core:develop-142'
implementation 'com.tangem.tangem-sdk-kotlin:android:develop-142'

View file

@ -40,9 +40,9 @@ class HomeFragment : Fragment(R.layout.fragment_home), StoreSubscriber<HomeState
onScanButtonClick = { store.dispatch(HomeAction.ReadCard) },
onShopButtonClick = { store.dispatch(HomeAction.GoToShop(getRegionProvider())) },
onSearchTokensClick = {
store.dispatch(NavigationAction.NavigateTo(AppScreen.AddTokens))
store.dispatch(TokensAction.AllowToAddTokens(false))
store.dispatch(TokensAction.LoadCurrencies())
store.dispatch(NavigationAction.NavigateTo(AppScreen.AddTokens))
}
)
}

View file

@ -2,6 +2,7 @@ package com.tangem.tap.features.tokens.redux
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.DerivationStyle
import com.tangem.tap.domain.tasks.product.ScanResponse
import com.tangem.tap.domain.tokens.Currency
import com.tangem.tap.features.wallet.redux.WalletData
import org.rekotlin.Action
@ -12,13 +13,17 @@ sealed class TokensAction : Action {
data class AllowToAddTokens(val allow: Boolean) : TokensAction()
data class LoadCurrencies(val supportedBlockchains: List<Blockchain>? = null) : TokensAction() {
data class LoadCurrencies(
val supportedBlockchains: List<Blockchain>? = null,
val scanResponse: ScanResponse? = null
) : TokensAction() {
data class Success(val currencies: List<Currency>) : TokensAction()
}
data class SetAddedCurrencies(
val wallets: List<WalletData>, val derivationStyle: DerivationStyle?
) : TokensAction()
) : TokensAction()
data class SetNonRemovableCurrencies(val wallets: List<WalletData>) : TokensAction()
data class SaveChanges(

View file

@ -27,6 +27,7 @@ import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.rekotlin.Middleware
@ -49,10 +50,13 @@ class TokensMiddleware {
val scanResponse = store.state.globalState.scanResponse
val isTestcard = scanResponse?.card?.isTestCard ?: false
val currencies = currenciesRepository.getSupportedTokens(isTestcard)
.filter(action.supportedBlockchains?.toSet())
store.dispatch(TokensAction.LoadCurrencies.Success(currencies))
scope.launch {
val currencies = async { currenciesRepository.getSupportedTokens(isTestcard)
.filter(action.supportedBlockchains?.toSet()) }
val delay = async { delay(600) }
delay.await()
store.dispatchOnMain(TokensAction.LoadCurrencies.Success(currencies.await()))
}
}
private fun handleSaveChanges(action: TokensAction.SaveChanges) {
@ -118,7 +122,7 @@ class TokensMiddleware {
derivedKeys = updatedDerivedKeys
)
store.dispatchOnMain(GlobalAction.SaveScanNoteResponse(updatedScanResponse))
submitAdd(blockchains, tokens, scanResponse)
submitAdd(blockchains, tokens, updatedScanResponse)
delay(DELAY_SDK_DIALOG_CLOSE)
store.dispatchOnMain(NavigationAction.PopBackTo())

View file

@ -15,6 +15,7 @@ private fun internalReduce(action: Action, state: AppState): TokensState {
val tokensState = state.tokensState
return when (action) {
is TokensAction.ResetState -> TokensState()
is TokensAction.LoadCurrencies -> tokensState.copy(scanResponse = action.scanResponse)
is TokensAction.LoadCurrencies.Success -> {
tokensState.copy(currencies = action.currencies)
}

View file

@ -3,6 +3,7 @@ package com.tangem.tap.features.tokens.redux
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.DerivationStyle
import com.tangem.blockchain.common.Token
import com.tangem.tap.domain.tasks.product.ScanResponse
import com.tangem.tap.domain.tokens.Currency
import com.tangem.tap.domain.tokens.fromNetworkId
import com.tangem.tap.features.wallet.redux.WalletData
@ -16,7 +17,8 @@ data class TokensState(
val nonRemovableBlockchains: List<Blockchain> = emptyList(),
val currencies: List<Currency> = emptyList(),
val allowToAdd: Boolean = true,
val derivationStyle: DerivationStyle? = null
val derivationStyle: DerivationStyle? = null,
val scanResponse: ScanResponse? = null
) : StateType
typealias ContractAddress = String

View file

@ -97,6 +97,7 @@ class AddTokensFragment : Fragment(R.layout.fragment_add_tokens),
if (activity == null || view == null) return
val toolbarTitle =
if (state.allowToAdd) R.string.add_tokens_title else R.string.search_tokens_title
tokensState.value = state
binding.toolbar.title = getString(toolbarTitle)
}

View file

@ -1,12 +1,16 @@
package com.tangem.tap.features.tokens.ui.compose
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
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.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
@ -16,6 +20,7 @@ import com.tangem.blockchain.common.Blockchain
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.TapWorkarounds.useOldStyleDerivation
import com.tangem.tap.domain.tokens.Currency
import com.tangem.tap.domain.tokens.fromNetworkId
import com.tangem.tap.features.tokens.redux.ContractAddress
@ -59,7 +64,6 @@ fun CurrenciesScreen(
}
Scaffold(
// topBar =,
floatingActionButton = {
if (tokensState.value.allowToAdd) SaveChangesButton(isKeyboardOpen) {
onSaveChanges(addedTokensState.value, addedBlockchainsState.value)
@ -68,19 +72,39 @@ fun CurrenciesScreen(
floatingActionButtonPosition = FabPosition.Center,
) {
Column {
if (tokensState.value.allowToAdd) CurrenciesWarning()
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,
onNetworkItemClicked = onNetworkItemClicked
)
AnimatedVisibility(
visible = tokensState.value.currencies.isEmpty(),
enter = fadeIn(),
exit = fadeOut()
){
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
) {
CircularProgressIndicator(
color = Color(0xFF1ACE80)
)
}
}
AnimatedVisibility(
visible = tokensState.value.currencies.isNotEmpty(),
enter = fadeIn(animationSpec = tween(1000)),
exit = fadeOut(animationSpec = tween(1000))
) {
Column {
if (tokensState.value.scanResponse?.card?.useOldStyleDerivation == true) CurrenciesWarning()
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,
onNetworkItemClicked = onNetworkItemClicked
)
}
}
}

View file

@ -2,12 +2,14 @@ package com.tangem.tap.features.tokens.ui.compose
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
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.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -41,9 +43,15 @@ fun NetworkItem(
Row(
modifier = Modifier
.fillMaxWidth()
.combinedClickable {
if (contract != null) onNetworkItemClicked(contract.address)
}
.combinedClickable(
enabled = allowToAdd,
onLongClick = {
if (contract != null) onNetworkItemClicked(contract.address)
},
onClick = {},
indication = null,
interactionSource = remember { MutableInteractionSource() }
)
) {
SubcomposeAsyncImage(
model = if (added) blockchain.getRoundIconRes() else blockchain.getGreyedOutIconRes(),
@ -70,7 +78,7 @@ fun NetworkItem(
)
Spacer(modifier = Modifier.size(3.dp))
Text(
text = if (isBlockchain) "MAIN" else blockchain.getNetworkName().uppercase(),
text = if (isBlockchain) "MAIN" else blockchain.getNetworkName().uppercase(),
fontSize = 13.sp,
fontWeight = FontWeight.Normal,
color = if (!isBlockchain) Color(0xFF8E8E93) else Color(0xFF1ACE80),

View file

@ -24,7 +24,10 @@ sealed class WalletAction : Action {
}
data class LoadWallet(val blockchain: BlockchainNetwork? = null) : WalletAction() {
data class LoadWallet(
val blockchain: BlockchainNetwork? = null,
val walletManager: WalletManager? = null
) : WalletAction() {
data class Success(val wallet: Wallet, val blockchain: BlockchainNetwork) : WalletAction()
data class NoAccount(
val wallet: Wallet,

View file

@ -68,7 +68,7 @@ class MultiWalletMiddleware {
)
)
store.dispatch(
WalletAction.LoadWallet(action.blockchain)
WalletAction.LoadWallet(action.blockchain, action.walletManager)
)
}
is WalletAction.MultiWallet.SaveCurrencies -> {

View file

@ -70,6 +70,7 @@ class WalletMiddleware {
}.awaitAll()
} else {
val walletManager = walletState.getWalletManager(action.blockchain)
?: action.walletManager
walletManager?.let { globalState.tapWalletManager.loadWalletData(it) }
}
}

View file

@ -58,13 +58,11 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
override fun onStart() {
super.onStart()
store.subscribe(this) { state ->
state.skipRepeats { oldState, newState ->
oldState.walletState == newState.walletState
}.select { it.walletState }
state.select { it.walletState }
}
walletView.setFragment(this, binding)
// store.dispatch(WalletAction.UpdateWallet(force = false))
store.dispatch(WalletAction.LoadWallet())
// store.dispatch(WalletAction.LoadWallet())
}
override fun onStop() {

View file

@ -101,18 +101,25 @@ class MultiWalletView : WalletView {
binding.btnAddToken.setOnClickListener {
val card = store.state.globalState.scanResponse!!.card
store.dispatch(TokensAction.LoadCurrencies(
supportedBlockchains = currenciesRepository.getBlockchains(
card.firmwareVersion,
card.isTestCard
)))
store.dispatch(
TokensAction.LoadCurrencies(
supportedBlockchains = currenciesRepository.getBlockchains(
card.firmwareVersion,
card.isTestCard
),
scanResponse = store.state.globalState.scanResponse
)
)
store.dispatch(TokensAction.AllowToAddTokens(true))
store.dispatch(TokensAction.SetAddedCurrencies(
wallets = state.walletsData,
derivationStyle = card.derivationStyle
))
store.dispatch(TokensAction.SetNonRemovableCurrencies(
state.walletsData.filterNot { state.canBeRemoved(it) })
store.dispatch(
TokensAction.SetAddedCurrencies(
wallets = state.walletsData,
derivationStyle = card.derivationStyle
)
)
store.dispatch(
TokensAction.SetNonRemovableCurrencies(
state.walletsData.filterNot { state.canBeRemoved(it) })
)
store.dispatch(NavigationAction.NavigateTo(AppScreen.AddTokens))
}