Updated on 2026-08-14

This commit is contained in:
Tangem 2022-09-29 16:36:42 +04:00
commit 7351aa2878
12 changed files with 109 additions and 51 deletions

View file

@ -138,36 +138,7 @@ class TapWalletManager {
private suspend fun loadMultiWalletData(
scanResponse: ScanResponse,
) {
when (val tokensResult = userTokensRepository.getUserTokens(scanResponse.card)) {
is Result.Success -> {
withMainContext {
val blockchainNetworks = tokensResult.data.toBlockchainNetworks()
val walletManagers = walletManagerFactory.makeWalletManagersForApp(scanResponse, tokensResult.data)
store.dispatch(
WalletAction.MultiWallet.AddBlockchains(
blockchains = blockchainNetworks,
walletManagers = walletManagers,
save = false,
),
)
blockchainNetworks.filter { it.tokens.isNotEmpty() }
.map {
store.dispatch(
WalletAction.MultiWallet.AddTokens(
tokens = it.tokens,
blockchain = it,
save = false,
),
)
}
checkIfDerivationsAreMissing(blockchainNetworks, scanResponse)
}
}
is Result.Failure -> {
return
}
}
loadUserCurrencies(scanResponse, walletManagerFactory)
}
private fun checkIfDerivationsAreMissing(blockchainNetworks: List<BlockchainNetwork>, scanResponse: ScanResponse) {
@ -207,7 +178,35 @@ class TapWalletManager {
}
}
private suspend fun loadUserCurrencies(scanResponse: ScanResponse, walletManagerFactory: WalletManagerFactory) {
val userTokens = userTokensRepository.getUserTokens(scanResponse.card)
withMainContext {
val blockchainNetworks = userTokens.toBlockchainNetworks()
val walletManagers = walletManagerFactory.makeWalletManagersForApp(scanResponse, userTokens)
store.dispatch(
WalletAction.MultiWallet.AddBlockchains(
blockchains = blockchainNetworks,
walletManagers = walletManagers,
save = false,
),
)
blockchainNetworks.filter { it.tokens.isNotEmpty() }
.map {
store.dispatch(
WalletAction.MultiWallet.AddTokens(
tokens = it.tokens,
blockchain = it,
save = false,
),
)
}
checkIfDerivationsAreMissing(blockchainNetworks, scanResponse)
}
}
suspend fun reloadData(data: ScanResponse) {
loadUserCurrencies(data, walletManagerFactory)
withContext(Dispatchers.Main) {
getActionIfUnknownBlockchainOrEmptyWallet(data)?.let {
store.dispatch(it)

View file

@ -24,20 +24,20 @@ class UserTokensRepository(
private val storageService: UserTokensStorageService,
private val networkService: UserTokensNetworkService,
) {
suspend fun getUserTokens(card: Card): Result<List<Currency>> {
suspend fun getUserTokens(card: Card): List<Currency> {
if (DemoHelper.isDemoCardId(card.cardId)) {
return Result.Success(loadDemoCurrencies())
return loadDemoCurrencies()
}
val userId = card.getUserId()
if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) {
return Result.Success(loadTokensOffline(card, userId))
return loadTokensOffline(card, userId)
}
return when (val networkResult = networkService.getUserTokens(userId)) {
is Result.Success -> {
val tokens = networkResult.data.tokens.map { Currency.fromTokenResponse(it) }
storageService.saveUserTokens(card.getUserId(), tokens)
Result.Success(tokens)
tokens
}
is Result.Failure -> {
handleGetUserTokensFailure(card = card, userId = userId, error = networkResult.error)
@ -73,16 +73,16 @@ class UserTokensRepository(
card: Card,
userId: String,
error: Throwable,
): Result<List<Currency>> {
): List<Currency> {
return when (error) {
is NoDataError -> {
val tokens = storageService.getUserTokens(card)
coroutineScope { launch { networkService.saveUserTokens(userId = userId, tokens = tokens) } }
Result.Success(tokens)
tokens
}
else -> {
val tokens = storageService.getUserTokens(userId) ?: storageService.getUserTokens(card)
Result.Success(tokens)
tokens
}
}
}
@ -103,7 +103,7 @@ class UserTokensRepository(
}
companion object {
const val MESSAGE = "AccountID"
const val MESSAGE = "UserWalletID"
fun init(context: Context, tangemTechService: TangemTechService): UserTokensRepository {
val fileReader = AndroidFileReader(context)
val oldUserTokensRepository = OldUserTokensRepository(

View file

@ -79,17 +79,21 @@ private fun handleOtherCardsAction(action: Action, dispatch: DispatchFunction) {
val primaryBlockchain = updatedResponse.getBlockchain()
val blockchainNetworks = if (primaryBlockchain != Blockchain.Unknown) {
val primaryToken = updatedResponse.getPrimaryToken()
val blockchainNetwork = BlockchainNetwork(primaryBlockchain, updatedResponse.card).updateTokens(
listOfNotNull(primaryToken))
val blockchainNetwork =
BlockchainNetwork(primaryBlockchain, updatedResponse.card).updateTokens(
listOfNotNull(primaryToken),
)
listOf(blockchainNetwork)
} else {
listOf(
BlockchainNetwork(Blockchain.Bitcoin, updatedResponse.card),
BlockchainNetwork(Blockchain.Ethereum, updatedResponse.card)
BlockchainNetwork(Blockchain.Ethereum, updatedResponse.card),
)
}
store.dispatch(WalletAction.MultiWallet.SaveCurrencies(blockchainNetworks))
store.dispatch(
WalletAction.MultiWallet.SaveCurrencies(blockchainNetworks, updatedResponse.card),
)
delay(DELAY_SDK_DIALOG_CLOSE)
store.dispatch(OnboardingOtherCardsAction.SetStepOfScreen(OnboardingOtherCardsStep.Done))

View file

@ -39,7 +39,7 @@ sealed class WalletAction : Action {
data class NoAccount(
val wallet: Wallet,
val blockchain: BlockchainNetwork,
val amountToCreateAccount: String
val amountToCreateAccount: String,
) : WalletAction()
data class Failure(val wallet: Wallet, val errorMessage: String? = null) : WalletAction()
@ -47,6 +47,10 @@ sealed class WalletAction : Action {
data class SetArtworkId(val artworkId: String?) : WalletAction()
sealed class UserTokens : WalletAction() {
object Loading : UserTokens()
object Loaded : UserTokens()
}
sealed class MultiWallet : WalletAction() {
data class SetIsMultiwalletAllowed(val isMultiwalletAllowed: Boolean) : MultiWallet()

View file

@ -45,6 +45,7 @@ data class WalletState(
val totalBalance: TotalBalance? = null,
val showBackupWarning: Boolean = false,
val missingDerivations: List<BlockchainNetwork> = emptyList(),
val loadingUserTokens: Boolean = false,
) : StateType {
// if you do not delegate - the application crashes on startup,

View file

@ -314,6 +314,8 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
is WalletAction.AppCurrencyAction -> {
newState = appCurrencyReducer.reduce(action, newState)
}
is WalletAction.UserTokens.Loading -> newState = newState.copy(loadingUserTokens = true)
is WalletAction.UserTokens.Loaded -> newState = newState.copy(loadingUserTokens = false)
else -> { /* no-op */
}
}

View file

@ -81,6 +81,8 @@ class MultiWalletView : WalletView() {
handleRescanWarning(binding, state.missingDerivations.isNotEmpty())
walletsAdapter.submitList(state.walletsData, state.primaryBlockchain, state.primaryToken)
binding.pbLoadingUserTokens.show(state.loadingUserTokens)
binding.btnAddToken.setOnClickListener {
val card = store.state.globalState.scanResponse!!.card
store.dispatch(

View file

@ -20,6 +20,7 @@ class SaltPaySingleWalletView : WalletView() {
btnAddToken.hide()
rvPendingTransaction.hide()
tvTwinCardNumber.hide()
pbLoadingUserTokens.hide()
lCardBalance.root.hide()
lAddress.root.hide()
lSingleWalletBalance.root.show()

View file

@ -37,6 +37,7 @@ class SingleWalletView : WalletView() {
rvMultiwallet.hide()
btnAddToken.hide()
rvPendingTransaction.hide()
pbLoadingUserTokens.hide()
lCardBalance.root.show()
lAddress.root.show()
lSingleWalletBalance.root.hide()

View file

@ -0,0 +1,24 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="44dp"
android:height="44dp"
android:autoMirrored="true"
android:viewportWidth="44"
android:viewportHeight="44">
<path
android:fillColor="#F5F5F5"
android:pathData="M20,24m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0" />
<path
android:fillColor="#000000"
android:pathData="M13.333,17.25C13.333,16.836 13.684,16.5 14.118,16.5H25.882C26.316,16.5 26.667,16.836 26.667,17.25V21H13.333V17.25Z" />
<path
android:fillColor="#000000"
android:pathData="M13.333,24H18.039V31.5H14.118C13.684,31.5 13.333,31.164 13.333,30.75V24Z" />
<path
android:fillColor="#000000"
android:pathData="M26.667,24H21.961V31.5H25.882C26.316,31.5 26.667,31.164 26.667,30.75V24Z" />
<path
android:fillColor="#FFB71B"
android:pathData="M36,8m-6,0a6,6 0,1 1,12 0a6,6 0,1 1,-12 0"
android:strokeWidth="4"
android:strokeColor="#ffffff" />
</vector>

View file

@ -191,11 +191,31 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:nestedScrollingEnabled="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/rv_pending_transaction" />
<ProgressBar
android:id="@+id/pb_loading_user_tokens"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:indeterminateTint="@color/icon_accent"
android:indeterminateTintMode="src_atop"
android:nestedScrollingEnabled="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/rv_pending_transaction" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_wallets"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="rv_multiwallet,pb_loading_user_tokens" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_add_token"
style="@style/BaseTapButton"
@ -210,7 +230,7 @@
android:visibility="gone"
app:cornerRadius="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/rv_multiwallet"
app:layout_constraintTop_toBottomOf="@id/barrier_wallets"
app:layout_constraintVertical_bias="0.0"
tools:layout_editor_absoluteX="16dp" />

View file

@ -8,9 +8,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingTop="14dp"
android:paddingTop="12dp"
android:paddingEnd="16dp"
android:paddingBottom="14dp">
android:paddingBottom="12dp">
<ImageView
android:id="@+id/iv_rescan_warning_icon"
@ -21,7 +21,7 @@
android:contentDescription="@null"
android:paddingBottom="4dp"
android:scaleType="center"
android:src="@drawable/ic_scan_card"
android:src="@drawable/ic_tangem_warning"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -33,8 +33,8 @@
android:layout_marginStart="8dp"
android:layout_marginEnd="16dp"
android:text="@string/main_scan_card_warning_view_title"
android:textColor="@color/textBlack"
android:textSize="14sp"
android:textColor="@color/text_primary_1"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@id/tv_rescan_warning_subtitle"
app:layout_constraintEnd_toStartOf="@id/iv_rescan_warning_end_icon"
@ -47,8 +47,8 @@
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/main_scan_card_warning_view_subtitle"
android:textColor="@color/iconGray"
android:textSize="12sp"
android:textColor="@color/text_secondary"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/tv_rescan_warning_title"
app:layout_constraintStart_toStartOf="@id/tv_rescan_warning_title"