Updated on 2026-08-14
This commit is contained in:
parent
ad95296768
commit
2a754c50cf
23 changed files with 584 additions and 202 deletions
|
|
@ -111,7 +111,8 @@ private fun onScanSuccess(scanResponse: ScanResponse) {
|
|||
if (scanResponse.isSaltPay()) {
|
||||
if (scanResponse.isSaltPayVisa()) {
|
||||
scope.launch {
|
||||
val result = OnboardingSaltPayHelper.isOnboardingCase(scanResponse)
|
||||
val (manager, config) = OnboardingSaltPayState.initDependency(scanResponse)
|
||||
val result = OnboardingSaltPayHelper.isOnboardingCase(scanResponse, manager)
|
||||
delay(500)
|
||||
withMainContext {
|
||||
when (result) {
|
||||
|
|
@ -119,10 +120,8 @@ private fun onScanSuccess(scanResponse: ScanResponse) {
|
|||
val isOnboardingCase = result.data
|
||||
if (isOnboardingCase) {
|
||||
store.dispatch(GlobalAction.Onboarding.Start(scanResponse, canSkipBackup = false))
|
||||
val (manager, config) = OnboardingSaltPayState.initDependency(scanResponse)
|
||||
store.dispatch(OnboardingSaltPayAction.Init.SetDependencies(manager, config))
|
||||
store.dispatch(OnboardingSaltPayAction.Update)
|
||||
// store.dispatch(OnboardingSaltPayAction.Init.DiscardBackupSteps)
|
||||
navigateTo(AppScreen.OnboardingWallet)
|
||||
} else {
|
||||
navigateTo(AppScreen.Wallet)
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ package com.tangem.tap.features.onboarding
|
|||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.domain.common.extensions.successOr
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.SaltPayRegistrationManager
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayRegistrationError
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.redux.OnboardingSaltPayState
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.redux.SaltPayRegistrationStep
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.redux.toSaltPayStep
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.redux.updateSaltPayStatus
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -14,19 +14,22 @@ import com.tangem.tap.features.onboarding.products.wallet.saltPay.redux.toSaltPa
|
|||
class OnboardingSaltPayHelper {
|
||||
companion object {
|
||||
|
||||
suspend fun isOnboardingCase(scanResponse: ScanResponse): Result<Boolean> {
|
||||
suspend fun isOnboardingCase(
|
||||
scanResponse: ScanResponse,
|
||||
manager: SaltPayRegistrationManager
|
||||
): Result<Boolean> {
|
||||
return try {
|
||||
val (manager, config) = OnboardingSaltPayState.initDependency(scanResponse)
|
||||
val registrationResponseItem = manager.checkRegistration().successOr { return it }
|
||||
val registrationStep = registrationResponseItem.toSaltPayStep()
|
||||
manager.checkHasGas().successOr { return it }
|
||||
val status = manager.updateSaltPayStatus(
|
||||
amountToClaim = null,
|
||||
step = SaltPayRegistrationStep.None,
|
||||
).successOr { return it }
|
||||
|
||||
val isRegistrationOnboardingCase = registrationStep != SaltPayRegistrationStep.Finished
|
||||
val isBackupOnboardingCase = scanResponse.card.backupStatus?.isActive == false
|
||||
Result.Success(isRegistrationOnboardingCase || isBackupOnboardingCase)
|
||||
val isRegistrationCase = status.step != SaltPayRegistrationStep.ClaimSuccess
|
||||
val isBackupCase = scanResponse.card.backupStatus?.isActive == false
|
||||
Result.Success(isRegistrationCase || isBackupCase)
|
||||
} catch (ex: Exception) {
|
||||
Result.Failure(ex)
|
||||
} catch (error: SaltPayRegistrationError){
|
||||
} catch (error: SaltPayRegistrationError) {
|
||||
Result.Failure(error)
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +40,7 @@ class OnboardingSaltPayHelper {
|
|||
Result.Success(isBackupOnboardingCase)
|
||||
} catch (ex: Exception) {
|
||||
Result.Failure(ex)
|
||||
} catch (error: SaltPayRegistrationError){
|
||||
} catch (error: SaltPayRegistrationError) {
|
||||
Result.Failure(error)
|
||||
}
|
||||
}
|
||||
|
|
@ -47,7 +50,7 @@ class OnboardingSaltPayHelper {
|
|||
Result.Success(false)
|
||||
} catch (ex: Exception) {
|
||||
Result.Failure(ex)
|
||||
} catch (error: SaltPayRegistrationError){
|
||||
} catch (error: SaltPayRegistrationError) {
|
||||
Result.Failure(error)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,12 @@ import com.tangem.common.CompletionResult
|
|||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.tap.DELAY_SDK_DIALOG_CLOSE
|
||||
import com.tangem.tap.common.extensions.*
|
||||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||
import com.tangem.tap.common.extensions.dispatchErrorNotification
|
||||
import com.tangem.tap.common.extensions.dispatchOpenUrl
|
||||
import com.tangem.tap.common.extensions.getAddressData
|
||||
import com.tangem.tap.common.extensions.getToUpUrl
|
||||
import com.tangem.tap.common.extensions.onCardScanned
|
||||
import com.tangem.tap.common.postUi
|
||||
import com.tangem.tap.common.redux.AppDialog
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
|
|
@ -15,6 +20,7 @@ import com.tangem.tap.domain.TapError
|
|||
import com.tangem.tap.domain.extensions.hasWallets
|
||||
import com.tangem.tap.domain.extensions.makePrimaryWalletManager
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.features.onboarding.WalletBalanceFetcher
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
import com.tangem.tap.features.wallet.redux.ProgressState
|
||||
import com.tangem.tap.scope
|
||||
|
|
@ -115,16 +121,16 @@ private fun handleNoteAction(appState: () -> AppState?, action: Action, dispatch
|
|||
val balanceIsLoading = noteState.walletBalance.copy(
|
||||
currency = Currency.Blockchain(
|
||||
walletManager.wallet.blockchain,
|
||||
walletManager.wallet.publicKey.derivationPath?.rawPath
|
||||
walletManager.wallet.publicKey.derivationPath?.rawPath,
|
||||
),
|
||||
state = ProgressState.Loading,
|
||||
error = null,
|
||||
criticalError = null
|
||||
criticalError = null,
|
||||
)
|
||||
store.dispatch(OnboardingNoteAction.Balance.Set(balanceIsLoading))
|
||||
|
||||
scope.launch {
|
||||
val loadedBalance = onboardingManager.updateBalance(walletManager)
|
||||
val loadedBalance = WalletBalanceFetcher().updateBalance(walletManager)
|
||||
delay(if (isLoadedBefore) 0 else 300)
|
||||
loadedBalance.criticalError?.let { store.dispatchErrorNotification(it) }
|
||||
withMainContext {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ data class OnboardingWalletState(
|
|||
}
|
||||
|
||||
fun getMaxProgress(): Int = when {
|
||||
isSaltPay -> 12
|
||||
isSaltPay -> 14
|
||||
else -> 6
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +41,6 @@ data class OnboardingWalletState(
|
|||
when (backupState.backupStep) {
|
||||
BackupStep.InitBackup -> 2
|
||||
BackupStep.ScanOriginCard -> 3
|
||||
|
||||
BackupStep.AddBackupCards -> 4
|
||||
BackupStep.EnterAccessCode -> 4
|
||||
BackupStep.ReenterAccessCode -> 4
|
||||
|
|
@ -52,13 +51,15 @@ data class OnboardingWalletState(
|
|||
}
|
||||
step == OnboardingWalletStep.SaltPay && isSaltPay -> {
|
||||
when (onboardingSaltPayState!!.step) {
|
||||
SaltPayRegistrationStep.NoGas -> 1
|
||||
SaltPayRegistrationStep.None, SaltPayRegistrationStep.NoGas -> 0
|
||||
SaltPayRegistrationStep.NeedPin -> 7
|
||||
SaltPayRegistrationStep.CardRegistration -> 8
|
||||
SaltPayRegistrationStep.KycIntro -> 9
|
||||
SaltPayRegistrationStep.KycStart -> 10
|
||||
SaltPayRegistrationStep.KycWaiting -> 11
|
||||
SaltPayRegistrationStep.Finished -> getMaxProgress()
|
||||
SaltPayRegistrationStep.Claim -> 12
|
||||
SaltPayRegistrationStep.ClaimInProgress -> 13
|
||||
SaltPayRegistrationStep.ClaimSuccess -> getMaxProgress()
|
||||
}
|
||||
}
|
||||
step == OnboardingWalletStep.Done -> getMaxProgress()
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.tangem.blockchain.common.Amount
|
|||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.blockchain.common.TransactionSigner
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
|
|
@ -42,6 +43,8 @@ class GnosisRegistrator(
|
|||
else -> throw IllegalArgumentException("GnosisRegistrator supports only the SaltPay blockchain")
|
||||
}
|
||||
|
||||
private val addressTreasureSafe = "0x8e9260a049d3Aa9ac60D0d4F27017320E0e2396B"
|
||||
|
||||
private val atomicNonce = AtomicLong()
|
||||
|
||||
suspend fun checkHasGas(): Result<Boolean> {
|
||||
|
|
@ -142,6 +145,21 @@ class GnosisRegistrator(
|
|||
return Result.Success(compiledEthereumTransaction)
|
||||
}
|
||||
|
||||
suspend fun getAllowance(): Result<Amount> {
|
||||
return walletManager.getAllowance(addressTreasureSafe, token)
|
||||
}
|
||||
|
||||
suspend fun transferFrom(amountToClaim: BigDecimal, signer: TransactionSigner): Result<Unit> {
|
||||
val amount = Amount(token, amountToClaim)
|
||||
val feeAmount = walletManager.getFeeToTransferFrom(amount, addressTreasureSafe)
|
||||
.extractFeeAmount().successOr { return it }
|
||||
|
||||
val transactionData = walletManager.createTransferFromTransaction(amount, feeAmount, addressTreasureSafe)
|
||||
walletManager.transferFrom(transactionData, signer).successOr { return Result.Failure(it.error) }
|
||||
|
||||
return Result.Success(Unit)
|
||||
}
|
||||
|
||||
private fun Result<List<Amount>>.extractFeeAmount(): Result<Amount> {
|
||||
return when (this) {
|
||||
is Result.Success -> {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@ package com.tangem.tap.features.onboarding.products.wallet.saltPay
|
|||
|
||||
import android.net.Uri
|
||||
import com.tangem.blockchain.blockchains.ethereum.SignedEthereumTransaction
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.blockchain.common.TransactionSigner
|
||||
import com.tangem.blockchain.extensions.successOr
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.common.extensions.isZero
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.extensions.successOr
|
||||
import com.tangem.network.api.paymentology.AttestationResponse
|
||||
|
|
@ -11,6 +17,8 @@ import com.tangem.network.api.paymentology.RegisterWalletRequest
|
|||
import com.tangem.network.api.paymentology.RegisterWalletResponse
|
||||
import com.tangem.network.api.paymentology.RegistrationResponse
|
||||
import com.tangem.operations.attestation.AttestWalletKeyResponse
|
||||
import com.tangem.tap.common.extensions.safeUpdate
|
||||
import com.tangem.tap.domain.getFirstToken
|
||||
import com.tangem.tap.domain.tokens.UserWalletId
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayRegistrationError
|
||||
import com.tangem.tap.persistence.SaltPayRegistrationStorage
|
||||
|
|
@ -104,6 +112,38 @@ class SaltPayRegistrationManager(
|
|||
return result
|
||||
}
|
||||
|
||||
suspend fun getAmountToClaim(): Result<Amount> {
|
||||
val amount = gnosisRegistrator.getAllowance().successOr {
|
||||
return Result.Failure(SaltPayRegistrationError.FailedToGetFundsToClaim)
|
||||
}
|
||||
|
||||
return if (amount.value == null || amount.value?.isZero() == true) {
|
||||
Result.Failure(SaltPayRegistrationError.NoFundsToClaim)
|
||||
} else {
|
||||
Result.Success(amount)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun claim(amountToClaim: BigDecimal, signer: TransactionSigner): Result<Unit> {
|
||||
val result = gnosisRegistrator.transferFrom(amountToClaim, signer).successOr {
|
||||
return Result.Failure(SaltPayRegistrationError.ClaimTransactionFailed)
|
||||
}
|
||||
return Result.Success(Unit)
|
||||
}
|
||||
|
||||
suspend fun getTokenAmount(): Result<BigDecimal> {
|
||||
val wallet = gnosisRegistrator.walletManager.safeUpdate().successOr { return it }
|
||||
val token = wallet.getFirstToken().guard {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
val amountValue = wallet.amounts[AmountType.Token(token)]?.value.guard {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
return Result.Success(amountValue)
|
||||
}
|
||||
|
||||
fun makeRegistrationTask(challenge: ByteArray): SaltPayRegistrationTask {
|
||||
return SaltPayRegistrationTask(
|
||||
gnosisRegistrator = gnosisRegistrator,
|
||||
|
|
|
|||
|
|
@ -42,8 +42,13 @@ sealed class SaltPayRegistrationError(
|
|||
class CardDisabled(message: String?) : SaltPayRegistrationError(9, message)
|
||||
class CardNotPassed(message: String?) : SaltPayRegistrationError(10, message)
|
||||
object EmptyDynamicAttestResponse : SaltPayRegistrationError(11)
|
||||
object EmptyBackupCardScanned : SaltPayRegistrationError(12) //
|
||||
object WeakPin : SaltPayRegistrationError(13) //
|
||||
object EmptyBackupCardScanned : SaltPayRegistrationError(12)
|
||||
object WeakPin : SaltPayRegistrationError(13)
|
||||
|
||||
object FailedToGetFundsToClaim : SaltPayRegistrationError(14)
|
||||
object NoFundsToClaim : SaltPayRegistrationError(15)
|
||||
object ClaimTransactionFailed : SaltPayRegistrationError(16)
|
||||
object NotClaimed : SaltPayRegistrationError(17)
|
||||
|
||||
companion object {
|
||||
const val EMPTY_MESSAGE = ""
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.saltPay.redux
|
||||
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.SaltPayConfig
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.SaltPayRegistrationManager
|
||||
import org.rekotlin.Action
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -13,21 +15,25 @@ sealed class OnboardingSaltPayAction : Action {
|
|||
val registrationManager: SaltPayRegistrationManager,
|
||||
val saltPayConfig: SaltPayConfig,
|
||||
) : Init()
|
||||
|
||||
// only for tests
|
||||
object DiscardBackupSteps : Init()
|
||||
}
|
||||
|
||||
data class SetIsBusy(val isBusy: Boolean) : OnboardingSaltPayAction()
|
||||
data class SetInProgress(val isInProgress: Boolean) : OnboardingSaltPayAction()
|
||||
data class SetClaimRefreshInProgress(val isInProgress: Boolean) : OnboardingSaltPayAction()
|
||||
|
||||
data class SetAccessCode(val accessCode: String?) : OnboardingSaltPayAction()
|
||||
|
||||
object Update : OnboardingSaltPayAction()
|
||||
object RegisterCard : OnboardingSaltPayAction()
|
||||
object KYCStart : OnboardingSaltPayAction()
|
||||
object OnFinishKYC : OnboardingSaltPayAction()
|
||||
object OpenUtorgKYC : OnboardingSaltPayAction()
|
||||
object UtorgKYCRedirectSuccess : OnboardingSaltPayAction()
|
||||
object RegisterKYC : OnboardingSaltPayAction()
|
||||
object Claim : OnboardingSaltPayAction()
|
||||
object RefreshClaim : OnboardingSaltPayAction()
|
||||
|
||||
data class TrySetPin(val pin: String) : OnboardingSaltPayAction()
|
||||
data class SetPin(val pin: String) : OnboardingSaltPayAction()
|
||||
|
||||
data class SetStep(val newStep: SaltPayRegistrationStep? = null) : OnboardingSaltPayAction()
|
||||
data class SetAmountToClaim(val amount: Amount?) : OnboardingSaltPayAction()
|
||||
data class SetTokenBalance(val balanceValue: BigDecimal) : OnboardingSaltPayAction()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.saltPay.redux
|
||||
|
||||
import com.tangem.Message
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.extensions.successOr
|
||||
import com.tangem.common.Filter
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
|
|
@ -13,6 +14,8 @@ import com.tangem.tap.common.extensions.dispatchDialogShow
|
|||
import com.tangem.tap.common.extensions.dispatchErrorNotification
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.domain.TangemSigner
|
||||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.features.demo.DemoHelper
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletState
|
||||
|
|
@ -22,6 +25,7 @@ import com.tangem.tap.features.onboarding.products.wallet.saltPay.dialog.SaltPay
|
|||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.message.SaltPayRegistrationError
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.tap.tangemSdk
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -57,8 +61,55 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
|
|||
fun getState(): OnboardingSaltPayState = getOnboardingWalletState().onboardingSaltPayState!!
|
||||
|
||||
when (action) {
|
||||
is OnboardingSaltPayAction.Update -> {
|
||||
handleInProgress = true
|
||||
|
||||
val state = getState()
|
||||
scope.launch {
|
||||
val updateResult = state.saltPayManager.updateSaltPayStatus(
|
||||
amountToClaim = state.amountToClaim,
|
||||
step = state.step,
|
||||
).successOr {
|
||||
onException(it.error)
|
||||
return@launch
|
||||
}
|
||||
|
||||
handleInProgress = false
|
||||
withMainContext {
|
||||
// store.dispatch(OnboardingSaltPayAction.SetStep(updateResult.step))
|
||||
store.dispatch(OnboardingSaltPayAction.SetStep(SaltPayRegistrationStep.KycWaiting))
|
||||
}
|
||||
}
|
||||
|
||||
// handleIsBusy = true
|
||||
// scope.launch {
|
||||
// checkGasIfNeeded(state.saltPayManager, state.step).successOr {
|
||||
// onException(it.error)
|
||||
// return@launch
|
||||
// }
|
||||
//
|
||||
// registerKYCIfNeeded(state).successOr {
|
||||
// onException(it.error)
|
||||
// return@launch
|
||||
// }
|
||||
//
|
||||
// val amount = getAmountToClaimIfNeeded(state)?.let {
|
||||
// dispatchOnMain(OnboardingSaltPayAction.SetAmountToClaim(it))
|
||||
// }
|
||||
//
|
||||
// val newStep = checkRegistration(state, amount != null).successOr {
|
||||
// onException(it.error)
|
||||
// return@launch
|
||||
// }
|
||||
//
|
||||
// withMainContext {
|
||||
// handleIsBusy = false
|
||||
// store.dispatch(OnboardingSaltPayAction.SetStep(newStep))
|
||||
// }
|
||||
// }
|
||||
}
|
||||
is OnboardingSaltPayAction.RegisterCard -> {
|
||||
handleIsBusy = true
|
||||
handleInProgress = true
|
||||
val state = getState()
|
||||
|
||||
scope.launch {
|
||||
|
|
@ -107,18 +158,30 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
|
|||
}
|
||||
|
||||
withMainContext {
|
||||
handleIsBusy = false
|
||||
handleInProgress = false
|
||||
store.dispatch(OnboardingSaltPayAction.SetStep(SaltPayRegistrationStep.KycIntro))
|
||||
}
|
||||
}
|
||||
}
|
||||
is OnboardingSaltPayAction.KYCStart -> {
|
||||
is OnboardingSaltPayAction.OpenUtorgKYC -> {
|
||||
store.dispatch(OnboardingSaltPayAction.SetStep(SaltPayRegistrationStep.KycStart))
|
||||
}
|
||||
is OnboardingSaltPayAction.OnFinishKYC -> {
|
||||
is OnboardingSaltPayAction.UtorgKYCRedirectSuccess -> {
|
||||
store.dispatch(OnboardingSaltPayAction.RegisterKYC)
|
||||
}
|
||||
is OnboardingSaltPayAction.RegisterKYC -> {
|
||||
val state = getState()
|
||||
handleInProgress = true
|
||||
scope.launch {
|
||||
registerKYCIfNeeded(getState()).successOr {
|
||||
registerKYCIfNeeded(state.saltPayManager, state.step).successOr {
|
||||
onException(it.error)
|
||||
return@launch
|
||||
}
|
||||
handleInProgress = false
|
||||
if (state.readyToClaim()) {
|
||||
withMainContext { store.dispatch(OnboardingSaltPayAction.SetStep(SaltPayRegistrationStep.Claim)) }
|
||||
} else {
|
||||
onError(SaltPayRegistrationError.NoFundsToClaim)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -131,30 +194,58 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
|
|||
handleError = error
|
||||
}
|
||||
}
|
||||
is OnboardingSaltPayAction.Update -> {
|
||||
handleIsBusy = true
|
||||
is OnboardingSaltPayAction.Claim -> {
|
||||
val state = getState()
|
||||
handleInProgress = true
|
||||
|
||||
scope.launch {
|
||||
val amountToClaim = getAmountToClaimIfNeeded(state.saltPayManager, state.amountToClaim).guard {
|
||||
onException(SaltPayRegistrationError.NoFundsToClaim)
|
||||
return@launch
|
||||
}
|
||||
|
||||
val scanResponse = store.state.globalState.scanResponse
|
||||
?: store.state.globalState.onboardingState.onboardingManager?.scanResponse
|
||||
val signer = TangemSigner(
|
||||
card = scanResponse!!.card,
|
||||
tangemSdk = tangemSdk,
|
||||
initialMessage = Message(),
|
||||
accessCode = state.accessCode,
|
||||
) { signResponse ->
|
||||
store.dispatch(
|
||||
GlobalAction.UpdateWalletSignedHashes(
|
||||
walletSignedHashes = signResponse.totalSignedHashes,
|
||||
walletPublicKey = state.saltPayManager.walletPublicKey,
|
||||
remainingSignatures = signResponse.remainingSignatures,
|
||||
),
|
||||
)
|
||||
}
|
||||
state.saltPayManager.claim(amountToClaim.value!!, signer).successOr {
|
||||
dispatchOnMain(OnboardingSaltPayAction.SetStep(SaltPayRegistrationStep.Claim))
|
||||
onException(it.error)
|
||||
return@launch
|
||||
}
|
||||
|
||||
dispatchOnMain(OnboardingSaltPayAction.SetStep(SaltPayRegistrationStep.ClaimInProgress))
|
||||
dispatchOnMain(OnboardingSaltPayAction.RefreshClaim)
|
||||
}
|
||||
}
|
||||
is OnboardingSaltPayAction.RefreshClaim -> {
|
||||
handleInProgress = true
|
||||
handleClaimRefreshInProgress = true
|
||||
|
||||
val state = getState()
|
||||
scope.launch {
|
||||
checkGasIfNeeded(state.saltPayManager, state.step).successOr {
|
||||
onException(it.error)
|
||||
val balance = state.saltPayManager.getTokenAmount().successOr {
|
||||
handleException = it.error
|
||||
handleClaimRefreshInProgress = false
|
||||
return@launch
|
||||
}
|
||||
|
||||
registerKYCIfNeeded(state).successOr {
|
||||
onException(it.error)
|
||||
return@launch
|
||||
}
|
||||
|
||||
val newStep = checkRegistration(state).successOr {
|
||||
onException(it.error)
|
||||
return@launch
|
||||
}
|
||||
|
||||
withMainContext {
|
||||
handleIsBusy = false
|
||||
store.dispatch(OnboardingSaltPayAction.SetStep(newStep))
|
||||
}
|
||||
handleInProgress = false
|
||||
handleClaimRefreshInProgress = false
|
||||
dispatchOnMain(OnboardingSaltPayAction.SetTokenBalance(balance))
|
||||
dispatchOnMain(OnboardingSaltPayAction.SetStep(SaltPayRegistrationStep.ClaimSuccess))
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
|
|
@ -163,22 +254,93 @@ private fun handleOnboardingSaltPayAction(anyAction: Action, appState: () -> App
|
|||
}
|
||||
}
|
||||
|
||||
private var handleIsBusy: Boolean = false
|
||||
data class UpdateResult(
|
||||
val step: SaltPayRegistrationStep = SaltPayRegistrationStep.None,
|
||||
val amountToClaim: Amount? = null,
|
||||
)
|
||||
|
||||
suspend fun SaltPayRegistrationManager.updateSaltPayStatus(
|
||||
amountToClaim: Amount?,
|
||||
step: SaltPayRegistrationStep,
|
||||
): Result<UpdateResult> {
|
||||
Timber.d("updateSaltPayStatus")
|
||||
var updateResult = UpdateResult()
|
||||
|
||||
checkGasIfNeeded(this, step).successOr {
|
||||
return Result.Failure(it.error)
|
||||
|
||||
}
|
||||
registerKYCIfNeeded(this, step).successOr {
|
||||
return Result.Failure(it.error)
|
||||
|
||||
}
|
||||
val saltPayStep = checkRegistration(this).successOr {
|
||||
return Result.Failure(it.error)
|
||||
|
||||
}
|
||||
|
||||
val fetchedAmountToClaim = getAmountToClaimIfNeeded(this, amountToClaim)
|
||||
updateResult = when {
|
||||
saltPayStep == SaltPayRegistrationStep.Claim && fetchedAmountToClaim == null -> {
|
||||
updateResult.copy(
|
||||
step = SaltPayRegistrationStep.ClaimSuccess,
|
||||
amountToClaim = fetchedAmountToClaim,
|
||||
)
|
||||
}
|
||||
else -> updateResult.copy(
|
||||
step = saltPayStep,
|
||||
amountToClaim = fetchedAmountToClaim,
|
||||
)
|
||||
}
|
||||
|
||||
Timber.d("updateSaltPayStatus: success: %s", updateResult)
|
||||
return Result.Success(updateResult)
|
||||
}
|
||||
|
||||
private suspend fun getAmountToClaimIfNeeded(
|
||||
saltPayManager: SaltPayRegistrationManager,
|
||||
amountToClaim: Amount?,
|
||||
): Amount? {
|
||||
Timber.d("getAmountToClaimIfNeeded: for amount: %s", amountToClaim)
|
||||
if (amountToClaim != null) {
|
||||
Timber.d("getAmountToClaimIfNeeded: checks no need, amount already persist")
|
||||
return amountToClaim
|
||||
}
|
||||
|
||||
return when (val result = saltPayManager.getAmountToClaim()) {
|
||||
is Result.Success -> {
|
||||
Timber.d("getAmountToClaimIfNeeded: success: %s", result.data)
|
||||
return result.data
|
||||
}
|
||||
is Result.Failure -> {
|
||||
Timber.e(result.error, "getAmountToClaimIfNeeded: failure")
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var handleClaimRefreshInProgress: Boolean = false
|
||||
set(value) {
|
||||
field = value
|
||||
store.dispatchOnMain(OnboardingSaltPayAction.SetIsBusy(value))
|
||||
store.dispatchOnMain(OnboardingSaltPayAction.SetClaimRefreshInProgress(value))
|
||||
}
|
||||
|
||||
private var handleInProgress: Boolean = false
|
||||
set(value) {
|
||||
field = value
|
||||
store.dispatchOnMain(OnboardingSaltPayAction.SetInProgress(value))
|
||||
}
|
||||
|
||||
private suspend fun onError(error: SaltPayRegistrationError) {
|
||||
withMainContext {
|
||||
handleIsBusy = false
|
||||
handleInProgress = false
|
||||
handleError = error
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onException(error: Throwable) {
|
||||
withMainContext {
|
||||
handleIsBusy = false
|
||||
handleInProgress = false
|
||||
handleException = error
|
||||
}
|
||||
}
|
||||
|
|
@ -221,35 +383,58 @@ private suspend fun checkGasIfNeeded(
|
|||
saltPayManager: SaltPayRegistrationManager,
|
||||
step: SaltPayRegistrationStep,
|
||||
): Result<Unit> {
|
||||
Timber.d("checkGasIfNeeded: for step: %s", step)
|
||||
if (step == SaltPayRegistrationStep.KycStart ||
|
||||
step == SaltPayRegistrationStep.KycWaiting ||
|
||||
step == SaltPayRegistrationStep.Finished
|
||||
step == SaltPayRegistrationStep.ClaimSuccess
|
||||
) {
|
||||
Timber.d("checkGasIfNeeded: no need to check for step: %s", step)
|
||||
return Result.Success(Unit)
|
||||
}
|
||||
|
||||
return saltPayManager.checkHasGas()
|
||||
val result = saltPayManager.checkHasGas()
|
||||
when (result) {
|
||||
is Result.Success -> Timber.d("checkGasIfNeeded: has GAS")
|
||||
is Result.Failure -> Timber.d("checkGasIfNeeded: has NO GAS")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private suspend fun registerKYCIfNeeded(state: OnboardingSaltPayState): Result<Unit> {
|
||||
if (state.step != SaltPayRegistrationStep.KycStart) {
|
||||
private suspend fun registerKYCIfNeeded(
|
||||
saltPayManager: SaltPayRegistrationManager,
|
||||
step: SaltPayRegistrationStep,
|
||||
): Result<Unit> {
|
||||
Timber.d("registerKYCIfNeeded: step: %s", step)
|
||||
if (step != SaltPayRegistrationStep.KycStart) {
|
||||
Timber.d("registerKYCIfNeeded: return Success, because step != KycStart")
|
||||
return Result.Success(Unit)
|
||||
}
|
||||
|
||||
withMainContext {
|
||||
Timber.d("registerKYCIfNeeded: set new step: KycWaiting")
|
||||
store.dispatch(OnboardingSaltPayAction.SetStep(SaltPayRegistrationStep.KycWaiting))
|
||||
}
|
||||
return state.saltPayManager.registerKYC()
|
||||
|
||||
Timber.d("saltPayManager.registerKYC()")
|
||||
return saltPayManager.registerKYC()
|
||||
}
|
||||
|
||||
private suspend fun checkRegistration(
|
||||
state: OnboardingSaltPayState,
|
||||
saltPayManager: SaltPayRegistrationManager,
|
||||
): Result<SaltPayRegistrationStep> {
|
||||
Timber.d("checkRegistration")
|
||||
return try {
|
||||
val registrationResponseItem = state.saltPayManager.checkRegistration().successOr { return it }
|
||||
val registrationResponseItem = saltPayManager.checkRegistration().successOr {
|
||||
Timber.e(it.error, "checkRegistration: failure")
|
||||
return it
|
||||
}
|
||||
|
||||
Timber.d("checkRegistration: success: try convert to SaltPayStep")
|
||||
val step = registrationResponseItem.toSaltPayStep()
|
||||
Timber.d("checkRegistration: step: %s", step)
|
||||
Result.Success(step)
|
||||
} catch (ex: SaltPayRegistrationError) {
|
||||
Timber.e(ex, "checkRegistration: step")
|
||||
Result.Failure(ex)
|
||||
}
|
||||
}
|
||||
|
|
@ -260,8 +445,8 @@ fun RegistrationResponse.Item.toSaltPayStep(): SaltPayRegistrationStep {
|
|||
passed != true -> throw SaltPayRegistrationError.CardNotPassed(this.error)
|
||||
disabledByAdmin == true -> throw SaltPayRegistrationError.CardDisabled(this.error)
|
||||
|
||||
// go to success screen
|
||||
active == true -> SaltPayRegistrationStep.Finished
|
||||
// go to claim screen
|
||||
active == true -> SaltPayRegistrationStep.Claim
|
||||
|
||||
// pinSet is false, go toPin screen
|
||||
pinSet == false -> SaltPayRegistrationStep.NeedPin
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.saltPay.redux
|
||||
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.BackupStep
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletState
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletStep
|
||||
import org.rekotlin.Action
|
||||
|
||||
/**
|
||||
|
|
@ -31,20 +29,6 @@ private fun internalReduce(anyAction: Action, onboardingWalletState: OnboardingW
|
|||
val oldState = onboardingWalletState.onboardingSaltPayState ?: return onboardingWalletState
|
||||
|
||||
val newState = when (action) {
|
||||
OnboardingSaltPayAction.Init.DiscardBackupSteps -> {
|
||||
return onboardingWalletState.copy(
|
||||
step = OnboardingWalletStep.SaltPay,
|
||||
backupState = onboardingWalletState.backupState.copy(
|
||||
backupStep = BackupStep.Finished,
|
||||
maxBackupCards = 1,
|
||||
canSkipBackup = false,
|
||||
),
|
||||
onboardingSaltPayState = oldState.copy(
|
||||
isTest = true,
|
||||
step = SaltPayRegistrationStep.NeedPin,
|
||||
),
|
||||
)
|
||||
}
|
||||
is OnboardingSaltPayAction.SetAccessCode -> {
|
||||
oldState.copy(
|
||||
accessCode = action.accessCode,
|
||||
|
|
@ -62,19 +46,27 @@ private fun internalReduce(anyAction: Action, onboardingWalletState: OnboardingW
|
|||
)
|
||||
}
|
||||
}
|
||||
is OnboardingSaltPayAction.SetIsBusy -> {
|
||||
is OnboardingSaltPayAction.SetAmountToClaim -> {
|
||||
oldState.copy(
|
||||
isBusy = action.isBusy,
|
||||
amountToClaim = action.amount,
|
||||
)
|
||||
}
|
||||
is OnboardingSaltPayAction.SetTokenBalance -> {
|
||||
oldState.copy(
|
||||
tokenAmount = oldState.tokenAmount.copy(value = action.balanceValue),
|
||||
)
|
||||
}
|
||||
is OnboardingSaltPayAction.SetInProgress -> {
|
||||
oldState.copy(
|
||||
inProgress = action.isInProgress,
|
||||
)
|
||||
}
|
||||
is OnboardingSaltPayAction.SetClaimRefreshInProgress -> {
|
||||
oldState.copy(
|
||||
claimInProgress = action.isInProgress,
|
||||
)
|
||||
}
|
||||
else -> oldState
|
||||
// is OnboardingSaltPayAction.Init.PrepareAndSetDependencies -> oldState
|
||||
// OnboardingSaltPayAction.OnCreate -> oldState
|
||||
// is OnboardingSaltPayAction.OnFinishKYC -> oldState
|
||||
// is OnboardingSaltPayAction.Register -> oldState
|
||||
// is OnboardingSaltPayAction.TrySetPin -> oldState
|
||||
// is OnboardingSaltPayAction.Update -> oldState
|
||||
// is OnboardingSaltPayAction.TryUpdateStep -> oldState
|
||||
}
|
||||
|
||||
return when (newState) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.saltPay.redux
|
||||
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.common.json.MoshiJsonConverter
|
||||
import com.tangem.domain.common.SaltPayWorkaround
|
||||
import com.tangem.domain.common.ScanResponse
|
||||
import com.tangem.network.api.paymentology.PaymentologyApiService
|
||||
import com.tangem.tap.common.toggleWidget.WidgetState
|
||||
|
|
@ -17,6 +20,7 @@ import com.tangem.tap.features.wallet.redux.ProgressState
|
|||
import com.tangem.tap.persistence.SaltPayRegistrationStorage
|
||||
import com.tangem.tap.preferencesStorage
|
||||
import com.tangem.tap.store
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -27,14 +31,18 @@ data class OnboardingSaltPayState(
|
|||
val saltPayConfig: SaltPayConfig = SaltPayConfig.stub(),
|
||||
val pinCode: String? = null,
|
||||
val accessCode: String? = null,
|
||||
val step: SaltPayRegistrationStep = SaltPayRegistrationStep.NeedPin,
|
||||
val amountToClaim: Amount? = null,
|
||||
val tokenAmount: Amount = Amount(SaltPayWorkaround.tokenFrom(Blockchain.SaltPay), BigDecimal.ZERO),
|
||||
val step: SaltPayRegistrationStep = SaltPayRegistrationStep.None,
|
||||
val saltPayCardArtworkUrl: String? = null,
|
||||
val isBusy: Boolean = false,
|
||||
val isTest: Boolean = false,
|
||||
val inProgress: Boolean = false,
|
||||
val claimInProgress: Boolean = false,
|
||||
) {
|
||||
|
||||
val mainButtonState: WidgetState
|
||||
get() = if (isBusy) ProgressState.Loading else ProgressState.Done
|
||||
get() = if (inProgress) ProgressState.Loading else ProgressState.Done
|
||||
|
||||
fun readyToClaim(): Boolean = amountToClaim != null
|
||||
|
||||
val pinLength: Int = 4
|
||||
|
||||
|
|
@ -108,11 +116,14 @@ data class OnboardingSaltPayState(
|
|||
}
|
||||
|
||||
enum class SaltPayRegistrationStep {
|
||||
None,
|
||||
NoGas,
|
||||
NeedPin,
|
||||
CardRegistration,
|
||||
KycIntro,
|
||||
KycStart,
|
||||
KycWaiting,
|
||||
Finished;
|
||||
Claim,
|
||||
ClaimInProgress,
|
||||
ClaimSuccess;
|
||||
}
|
||||
|
|
@ -2,26 +2,34 @@ package com.tangem.tap.features.onboarding.products.wallet.saltPay.ui
|
|||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.OvershootInterpolator
|
||||
import android.widget.ProgressBar
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.constraintlayout.widget.ConstraintSet
|
||||
import androidx.core.view.children
|
||||
import androidx.transition.TransitionManager
|
||||
import coil.load
|
||||
import coil.size.Scale
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.tap.common.compose.PinCodeWidget
|
||||
import com.tangem.tap.common.extensions.beginDelayedTransition
|
||||
import com.tangem.tap.common.extensions.configureSettings
|
||||
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
|
||||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||
import com.tangem.tap.common.extensions.getDrawableCompat
|
||||
import com.tangem.tap.common.extensions.hide
|
||||
import com.tangem.tap.common.extensions.show
|
||||
import com.tangem.tap.common.extensions.stop
|
||||
import com.tangem.tap.common.extensions.toFormattedCurrencyString
|
||||
import com.tangem.tap.common.feedback.SupportInfo
|
||||
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.toggleWidget.IndeterminateProgressButtonWidget
|
||||
import com.tangem.tap.common.toggleWidget.RefreshBalanceWidget
|
||||
import com.tangem.tap.common.transitions.InternalNoteLayoutTransition
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.BackupState
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.BackupStep
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.OnboardingWalletAction
|
||||
|
|
@ -34,8 +42,12 @@ import com.tangem.tap.features.onboarding.products.wallet.saltPay.redux.Onboardi
|
|||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.redux.OnboardingSaltPayState
|
||||
import com.tangem.tap.features.onboarding.products.wallet.saltPay.redux.SaltPayRegistrationStep
|
||||
import com.tangem.tap.features.onboarding.products.wallet.ui.OnboardingWalletFragment
|
||||
import com.tangem.tap.features.wallet.redux.ProgressState
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import com.tangem.wallet.databinding.LayoutOnboardingContainerBottomBinding
|
||||
import com.tangem.wallet.databinding.LayoutOnboardingContainerTopBinding
|
||||
import com.tangem.wallet.databinding.LayoutOnboardingMainBinding
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -45,6 +57,11 @@ internal class OnboardingSaltPayView(
|
|||
) {
|
||||
|
||||
private val toolbar: MaterialToolbar by lazy { walletFragment.binding.toolbar }
|
||||
private val claimBinding: LayoutOnboardingMainBinding by lazy { walletFragment.bindingSaltPay.claim }
|
||||
|
||||
private val btnRefreshBalanceWidget by lazy {
|
||||
RefreshBalanceWidget(claimBinding.onboardingTopContainer.onboardingWalletContainer)
|
||||
}
|
||||
|
||||
private var progressButton: SaltPayProgressButton? = null
|
||||
|
||||
|
|
@ -86,11 +103,6 @@ internal class OnboardingSaltPayView(
|
|||
// walletFragment.loadImageIntoImageView(state.onboardingSaltPayState.saltPayCardArtworkUrl, imvFrontCard)
|
||||
// }
|
||||
// walletFragment.loadImageIntoImageView(state.cardArtworkUrl, imvFirstBackupCard)
|
||||
|
||||
//TODO: at now we can hide the image only by changing alpha channel to 0, because
|
||||
// the OnboardingWalletFragment and WalletCardsWidget manipulate it visibility through changing
|
||||
// View.VISIBILITY states.
|
||||
// imvSecondBackupCard.alpha = 0f
|
||||
}
|
||||
|
||||
fun showAddBackupCards(state: BackupState) = with(walletFragment.binding) {
|
||||
|
|
@ -123,10 +135,9 @@ internal class OnboardingSaltPayView(
|
|||
SaltPayRegistrationStep.KycIntro -> handleKycIntro()
|
||||
SaltPayRegistrationStep.KycStart -> handleKycStart(state)
|
||||
SaltPayRegistrationStep.KycWaiting -> handleKycWaiting()
|
||||
// SaltPayRegistrationStep.Claim -> handleKycWaiting()
|
||||
// SaltPayRegistrationStep.ClaimInProgress -> handleKycWaiting()
|
||||
// SaltPayRegistrationStep.ClaimSuccess -> handleKycWaiting()
|
||||
SaltPayRegistrationStep.Finished -> handleFinished()
|
||||
SaltPayRegistrationStep.Claim -> handleClaim(state)
|
||||
SaltPayRegistrationStep.ClaimInProgress -> handleClaim(state)
|
||||
SaltPayRegistrationStep.ClaimSuccess -> handleClaim(state)
|
||||
}
|
||||
progressButton?.changeState(state.mainButtonState)
|
||||
}
|
||||
|
|
@ -138,7 +149,7 @@ internal class OnboardingSaltPayView(
|
|||
}
|
||||
|
||||
private fun handleNeedPin() = with(walletFragment.bindingSaltPay) {
|
||||
toolbar.title = walletFragment.getString(R.string.onboarding_navbar_pin)
|
||||
toolbar.title = getString(R.string.onboarding_navbar_pin)
|
||||
showOnlyView(pinCode.root) {
|
||||
progressButton = SaltPayProgressButton(pinCode.root)
|
||||
progressButton?.mainView?.isEnabled = false
|
||||
|
|
@ -157,7 +168,7 @@ internal class OnboardingSaltPayView(
|
|||
}
|
||||
|
||||
private fun handleCardRegistration() = with(walletFragment.bindingSaltPay) {
|
||||
toolbar.title = walletFragment.getString(R.string.onboarding_navbar_register_wallet)
|
||||
toolbar.title = getString(R.string.onboarding_navbar_register_wallet)
|
||||
showOnlyView(connectCard.root) {
|
||||
progressButton = SaltPayProgressButton(connectCard.root)
|
||||
connectCard.btnConnect.setOnClickListener {
|
||||
|
|
@ -167,17 +178,17 @@ internal class OnboardingSaltPayView(
|
|||
}
|
||||
|
||||
private fun handleKycIntro() = with(walletFragment.bindingSaltPay) {
|
||||
toolbar.title = walletFragment.getString(R.string.onboarding_navbar_kyc_start)
|
||||
toolbar.title = getString(R.string.onboarding_navbar_kyc_start)
|
||||
showOnlyView(verifyIdentity.root) {
|
||||
progressButton = SaltPayProgressButton(verifyIdentity.root)
|
||||
verifyIdentity.btnVerify.setOnClickListener {
|
||||
store.dispatch(OnboardingSaltPayAction.KYCStart)
|
||||
store.dispatch(OnboardingSaltPayAction.OpenUtorgKYC)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleKycStart(state: OnboardingSaltPayState) = with(walletFragment.bindingSaltPay) {
|
||||
toolbar.title = walletFragment.getString(R.string.onboarding_navbar_kyc_start)
|
||||
toolbar.title = getString(R.string.onboarding_navbar_kyc_start)
|
||||
showOnlyView(webvVerifyIdentity) {
|
||||
progressButton = null
|
||||
webvVerifyIdentity.configureSettings()
|
||||
|
|
@ -185,7 +196,7 @@ internal class OnboardingSaltPayView(
|
|||
successUrl = state.saltPayManager.kycUrlProvider.doneUrl,
|
||||
onSuccess = {
|
||||
webvVerifyIdentity.stop()
|
||||
store.dispatch(OnboardingSaltPayAction.OnFinishKYC)
|
||||
store.dispatch(OnboardingSaltPayAction.UtorgKYCRedirectSuccess)
|
||||
},
|
||||
)
|
||||
webvVerifyIdentity.webChromeClient = UtorgWebChromeClient(walletFragment.requireActivity())
|
||||
|
|
@ -194,7 +205,7 @@ internal class OnboardingSaltPayView(
|
|||
}
|
||||
|
||||
private fun handleKycWaiting() = with(walletFragment.bindingSaltPay) {
|
||||
toolbar.title = walletFragment.getString(R.string.onboarding_navbar_kyc_waiting)
|
||||
toolbar.title = getString(R.string.onboarding_navbar_kyc_waiting)
|
||||
showOnlyView(verifyIdentityInProgress.root) {
|
||||
progressButton = SaltPayProgressButton(verifyIdentityInProgress.root)
|
||||
verifyIdentityInProgress.btnOpenSupportChat.setOnClickListener {
|
||||
|
|
@ -206,56 +217,105 @@ internal class OnboardingSaltPayView(
|
|||
}
|
||||
}
|
||||
|
||||
// private fun setupTopUpWalletState(state: OnboardingNoteState) = with(binding.onboardingActionContainer) {
|
||||
// if (state.isBuyAllowed) {
|
||||
// btnMainAction.setText(com.tangem.wallet.R.string.onboarding_top_up_button_but_crypto)
|
||||
// btnMainAction.setOnClickListener {
|
||||
// com.tangem.tap.store.dispatch(com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteAction.TopUp)
|
||||
// }
|
||||
//
|
||||
// btnAlternativeAction.isVisible = true
|
||||
// btnAlternativeAction.setText(com.tangem.wallet.R.string.onboarding_top_up_button_show_wallet_address)
|
||||
// btnAlternativeAction.setOnClickListener {
|
||||
// com.tangem.tap.store.dispatch(com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteAction.ShowAddressInfoDialog)
|
||||
// }
|
||||
// } else {
|
||||
// btnMainAction.setText(com.tangem.wallet.R.string.onboarding_button_receive_crypto)
|
||||
// btnMainAction.setOnClickListener {
|
||||
// com.tangem.tap.store.dispatch(com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteAction.ShowAddressInfoDialog)
|
||||
// }
|
||||
//
|
||||
// btnAlternativeAction.isVisible = false
|
||||
// }
|
||||
//
|
||||
// tvHeader.setText(com.tangem.wallet.R.string.onboarding_top_up_header)
|
||||
// if (state.balanceNonCriticalError == null) {
|
||||
// tvBody.setText(com.tangem.wallet.R.string.onboarding_top_up_body)
|
||||
// } else {
|
||||
// state.walletBalance.amountToCreateAccount?.let { amount ->
|
||||
// val tvBodyMessage = getString(
|
||||
// com.tangem.wallet.R.string.onboarding_top_up_body_no_account_error,
|
||||
// amount, state.walletBalance.currency.currencySymbol,
|
||||
// )
|
||||
// tvBody.text = tvBodyMessage
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// btnRefreshBalanceWidget.changeState(state.walletBalance.state)
|
||||
// if (btnRefreshBalanceWidget.isShowing != true) {
|
||||
// btnRefreshBalanceWidget.mainView.setOnClickListener {
|
||||
// com.tangem.tap.store.dispatch(com.tangem.tap.features.onboarding.products.note.redux.OnboardingNoteAction.Balance.Update)
|
||||
// }
|
||||
// }
|
||||
// binding.onboardingTopContainer.imvCardBackground
|
||||
// .setBackgroundDrawable(requireContext().getDrawableCompat(com.tangem.wallet.R.drawable.shape_rectangle_rounded_8))
|
||||
// updateConstraints(state.currentStep, com.tangem.wallet.R.layout.lp_onboarding_topup_wallet)
|
||||
// }
|
||||
private val topContainer: LayoutOnboardingContainerTopBinding by lazy { claimBinding.onboardingTopContainer }
|
||||
private val actionContainer: LayoutOnboardingContainerBottomBinding by lazy { claimBinding.onboardingActionContainer }
|
||||
private var previousStep: SaltPayRegistrationStep = SaltPayRegistrationStep.None
|
||||
|
||||
private fun handleFinished() {
|
||||
walletFragment.binding.onboardingRoot.beginDelayedTransition()
|
||||
walletFragment.bindingSaltPay.onboardingSaltpayContainer.hide()
|
||||
walletFragment.binding.onboardingWalletContainer.show()
|
||||
walletFragment.showSuccess()
|
||||
private fun handleClaim(state: OnboardingSaltPayState) = with(walletFragment.bindingSaltPay) {
|
||||
toolbar.title = getString(R.string.onboarding_navbar_claim)
|
||||
val btnMain = actionContainer.btnContainer.findViewById<MaterialButton>(R.id.btn_main_action)
|
||||
val tvHeader = actionContainer.tvHeader
|
||||
val tvBody = actionContainer.tvBody
|
||||
|
||||
showOnlyView(claimBinding.root) {
|
||||
// topContainer.progress.pbState.hide()
|
||||
progressButton = SaltPayProgressButton(actionContainer.root)
|
||||
topContainer.imvCardBackground.apply {
|
||||
setBackgroundDrawable(context.getDrawableCompat(R.drawable.shape_rectangle_rounded_8))
|
||||
}
|
||||
topContainer.imvFrontCard.load(R.drawable.img_salt_pay_visa) {
|
||||
scale(Scale.FILL)
|
||||
crossfade(enable = true)
|
||||
}
|
||||
actionContainer.btnAlternativeAction.hide()
|
||||
updateConstraints(state.step, R.layout.lp_onboarding_topup_wallet)
|
||||
}
|
||||
|
||||
btnRefreshBalanceWidget.changeState(if (state.claimInProgress) ProgressState.Loading else ProgressState.Done)
|
||||
if (btnRefreshBalanceWidget.isShowing != true) {
|
||||
btnRefreshBalanceWidget.mainView.setOnClickListener {
|
||||
store.dispatch(OnboardingSaltPayAction.RefreshClaim)
|
||||
}
|
||||
}
|
||||
val tokenAmountString = tokenAmountString(state)
|
||||
topContainer.onboardingTvBalance.tvBalanceValue.text = tokenAmountString ?: ""
|
||||
topContainer.onboardingTvBalance.tvBalanceCurrency.text = ""
|
||||
|
||||
when (state.step) {
|
||||
SaltPayRegistrationStep.Claim -> {
|
||||
btnRefreshBalanceWidget.mainView.hide()
|
||||
claimValueString(state)?.let {
|
||||
tvHeader.text = getString(R.string.onboarding_title_claim, it)
|
||||
}
|
||||
tvBody.text = getString(R.string.onboarding_subtitle_claim)
|
||||
|
||||
btnMain.text = getString(R.string.onboarding_button_claim)
|
||||
btnMain.setOnClickListener {
|
||||
store.dispatch(OnboardingSaltPayAction.Claim)
|
||||
}
|
||||
}
|
||||
SaltPayRegistrationStep.ClaimInProgress -> {
|
||||
btnRefreshBalanceWidget.mainView.show()
|
||||
tvHeader.text = getString(R.string.onboarding_title_claim_progress)
|
||||
tvBody.text = getString(R.string.onboarding_subtitle_claim_progress)
|
||||
btnMain.text = getString(R.string.onboarding_button_claim)
|
||||
}
|
||||
SaltPayRegistrationStep.ClaimSuccess -> {
|
||||
tvHeader.setText(R.string.common_success)
|
||||
tvBody.setText(R.string.onboarding_subtitle_success_claim)
|
||||
|
||||
btnMain.setText(R.string.onboarding_button_continue_wallet)
|
||||
btnMain.setOnClickListener {
|
||||
walletFragment.showConfetti(false)
|
||||
store.dispatch(OnboardingWalletAction.FinishOnboarding)
|
||||
}
|
||||
|
||||
btnRefreshBalanceWidget.mainView.setOnClickListener(null)
|
||||
updateConstraints(state.step, R.layout.lp_onboarding_done_activation)
|
||||
walletFragment.showConfetti(true)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
|
||||
// need to recreate after any step
|
||||
progressButton = SaltPayProgressButton(actionContainer.root)
|
||||
}
|
||||
|
||||
private fun tokenAmountString(state: OnboardingSaltPayState): String? {
|
||||
return state.tokenAmount.value?.toFormattedCurrencyString(
|
||||
decimals = state.tokenAmount.decimals,
|
||||
currency = state.tokenAmount.currencySymbol,
|
||||
)
|
||||
}
|
||||
|
||||
private fun claimValueString(state: OnboardingSaltPayState): String? {
|
||||
return state.amountToClaim?.value?.toFormattedCurrencyString(
|
||||
decimals = state.amountToClaim.decimals,
|
||||
currency = state.amountToClaim.currencySymbol,
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateConstraints(currentStep: SaltPayRegistrationStep, @LayoutRes layoutId: Int) {
|
||||
if (this.previousStep == currentStep) return
|
||||
|
||||
with(claimBinding.onboardingTopContainer) {
|
||||
val constraintSet = ConstraintSet()
|
||||
constraintSet.clone(root.context, layoutId)
|
||||
constraintSet.applyTo(onboardingWalletContainer)
|
||||
val transition = InternalNoteLayoutTransition()
|
||||
transition.interpolator = OvershootInterpolator()
|
||||
TransitionManager.beginDelayedTransition(onboardingWalletContainer, transition)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showOnlyView(view: View, onShowListener: (() -> Unit)? = null) {
|
||||
|
|
@ -265,6 +325,14 @@ internal class OnboardingSaltPayView(
|
|||
view.show { onShowListener?.invoke() }
|
||||
}
|
||||
|
||||
private fun getString(@StringRes resId: Int): String {
|
||||
return walletFragment.getString(resId)
|
||||
}
|
||||
|
||||
private fun getString(@StringRes resId: Int, vararg formatArgs: Any?): String {
|
||||
return walletFragment.getString(resId, *formatArgs)
|
||||
}
|
||||
|
||||
private class SaltPayProgressButton(
|
||||
root: ViewGroup,
|
||||
) : IndeterminateProgressButtonWidget(findButton(root), findProgress(root)) {
|
||||
|
|
|
|||
|
|
@ -169,9 +169,9 @@ class OnboardingWalletFragment : BaseFragment(R.layout.fragment_onboarding_walle
|
|||
}
|
||||
|
||||
private fun setupCreateWalletState() = with(binding) {
|
||||
layoutButtonsCommon.btnMainAction.setText(R.string.onboarding_create_wallet_button_create_wallet)
|
||||
layoutButtonsCommon.btnMainAction.setOnClickListener { store.dispatch(OnboardingWalletAction.CreateWallet) }
|
||||
layoutButtonsCommon.btnAlternativeAction.hide()
|
||||
layoutButtonsCommon.btnWalletMainAction.setText(R.string.onboarding_create_wallet_button_create_wallet)
|
||||
layoutButtonsCommon.btnWalletMainAction.setOnClickListener { store.dispatch(OnboardingWalletAction.CreateWallet) }
|
||||
layoutButtonsCommon.btnWalletAlternativeAction.hide()
|
||||
|
||||
toolbar.title = getText(R.string.onboarding_getting_started)
|
||||
|
||||
|
|
@ -205,12 +205,12 @@ class OnboardingWalletFragment : BaseFragment(R.layout.fragment_onboarding_walle
|
|||
tabLayoutBackupInfo.show()
|
||||
|
||||
with(layoutButtonsCommon) {
|
||||
btnMainAction.text = getText(R.string.onboarding_button_backup_now)
|
||||
btnMainAction.setOnClickListener { store.dispatch(BackupAction.StartBackup) }
|
||||
btnWalletMainAction.text = getText(R.string.onboarding_button_backup_now)
|
||||
btnWalletMainAction.setOnClickListener { store.dispatch(BackupAction.StartBackup) }
|
||||
|
||||
btnAlternativeAction.text = getText(R.string.onboarding_button_skip_backup)
|
||||
btnAlternativeAction.setOnClickListener { store.dispatch(BackupAction.DismissBackup) }
|
||||
btnAlternativeAction.show(state.canSkipBackup && !isSaltPay)
|
||||
btnWalletAlternativeAction.text = getText(R.string.onboarding_button_skip_backup)
|
||||
btnWalletAlternativeAction.setOnClickListener { store.dispatch(BackupAction.DismissBackup) }
|
||||
btnWalletAlternativeAction.show(state.canSkipBackup && !isSaltPay)
|
||||
}
|
||||
animator.showBackupIntro(state)
|
||||
}
|
||||
|
|
@ -223,9 +223,9 @@ class OnboardingWalletFragment : BaseFragment(R.layout.fragment_onboarding_walle
|
|||
)
|
||||
|
||||
with(layoutButtonsCommon) {
|
||||
btnMainAction.text = getString(R.string.onboarding_button_scan_origin_card)
|
||||
btnAlternativeAction.hide()
|
||||
btnMainAction.setOnClickListener { store.dispatch(BackupAction.ScanPrimaryCard) }
|
||||
btnWalletMainAction.text = getString(R.string.onboarding_button_scan_origin_card)
|
||||
btnWalletAlternativeAction.hide()
|
||||
btnWalletMainAction.setOnClickListener { store.dispatch(BackupAction.ScanPrimaryCard) }
|
||||
}
|
||||
|
||||
animator.showScanOriginCard()
|
||||
|
|
@ -323,16 +323,16 @@ class OnboardingWalletFragment : BaseFragment(R.layout.fragment_onboarding_walle
|
|||
if (isSaltPay) {
|
||||
tvHeader.text = getText(R.string.onboarding_saltpay_title_prepare_origin)
|
||||
tvBody.text = getString(R.string.onboarding_twins_interrupt_warning)
|
||||
layoutButtonsCommon.btnMainAction.text = getText(R.string.onboarding_saltpay_button_backup_origin)
|
||||
layoutButtonsCommon.btnWalletMainAction.text = getText(R.string.onboarding_saltpay_button_backup_origin)
|
||||
} else {
|
||||
tvHeader.text = getText(R.string.onboarding_title_prepare_origin)
|
||||
tvBody.text = getString(
|
||||
R.string.onboarding_subtitle_scan_primary_card_format,
|
||||
state.primaryCardId?.let { cardIdFormatter.getFormattedCardId(it) },
|
||||
)
|
||||
layoutButtonsCommon.btnMainAction.text = getText(R.string.onboarding_button_backup_origin)
|
||||
layoutButtonsCommon.btnWalletMainAction.text = getText(R.string.onboarding_button_backup_origin)
|
||||
}
|
||||
layoutButtonsCommon.btnMainAction.setOnClickListener { store.dispatch(BackupAction.WritePrimaryCard) }
|
||||
layoutButtonsCommon.btnWalletMainAction.setOnClickListener { store.dispatch(BackupAction.WritePrimaryCard) }
|
||||
|
||||
animator.showWritePrimaryCard(state)
|
||||
}
|
||||
|
|
@ -342,7 +342,7 @@ class OnboardingWalletFragment : BaseFragment(R.layout.fragment_onboarding_walle
|
|||
|
||||
layoutButtonsAddCards.root.hide()
|
||||
layoutButtonsCommon.root.show()
|
||||
layoutButtonsCommon.btnAlternativeAction.hide()
|
||||
layoutButtonsCommon.btnWalletAlternativeAction.hide()
|
||||
|
||||
imvCardBackground.hide()
|
||||
imvFirstBackupCard.show()
|
||||
|
|
@ -356,7 +356,7 @@ class OnboardingWalletFragment : BaseFragment(R.layout.fragment_onboarding_walle
|
|||
if (isSaltPay) {
|
||||
tvHeader.text = getString(R.string.onboarding_saltpay_title_backup_card)
|
||||
tvBody.text = getString(R.string.onboarding_twins_interrupt_warning)
|
||||
layoutButtonsCommon.btnMainAction.text = getString(R.string.onboarding_saltpay_title_backup_card)
|
||||
layoutButtonsCommon.btnWalletMainAction.text = getString(R.string.onboarding_saltpay_title_backup_card)
|
||||
} else {
|
||||
val cardIdFormatter = CardIdFormatter(CardIdDisplayFormat.LastMasked(4))
|
||||
tvHeader.text = getString(R.string.onboarding_title_backup_card_format, cardNumber)
|
||||
|
|
@ -364,12 +364,12 @@ class OnboardingWalletFragment : BaseFragment(R.layout.fragment_onboarding_walle
|
|||
R.string.onboarding_subtitle_scan_backup_card_format,
|
||||
cardIdFormatter.getFormattedCardId(state.backupCardIds[cardNumber - 1]),
|
||||
)
|
||||
layoutButtonsCommon.btnMainAction.text = getString(
|
||||
layoutButtonsCommon.btnWalletMainAction.text = getString(
|
||||
R.string.onboarding_button_backup_card_format,
|
||||
cardNumber,
|
||||
)
|
||||
}
|
||||
layoutButtonsCommon.btnMainAction.setOnClickListener {
|
||||
layoutButtonsCommon.btnWalletMainAction.setOnClickListener {
|
||||
store.dispatch(BackupAction.WriteBackupCard(cardNumber))
|
||||
}
|
||||
|
||||
|
|
@ -386,25 +386,33 @@ class OnboardingWalletFragment : BaseFragment(R.layout.fragment_onboarding_walle
|
|||
tabLayoutBackupInfo.hide()
|
||||
|
||||
tvBody.text = getText(R.string.onboarding_subtitle_success_tangem_wallet_onboarding)
|
||||
layoutButtonsCommon.btnMainAction.text = getText(R.string.onboarding_button_continue_wallet)
|
||||
layoutButtonsCommon.btnAlternativeAction.hide()
|
||||
layoutButtonsCommon.btnMainAction.setOnClickListener {
|
||||
vConfetti.lavConfetti.cancelAnimation()
|
||||
vConfetti.lavConfetti.hide()
|
||||
layoutButtonsCommon.btnWalletMainAction.text = getText(R.string.onboarding_button_continue_wallet)
|
||||
layoutButtonsCommon.btnWalletAlternativeAction.hide()
|
||||
layoutButtonsCommon.btnWalletMainAction.setOnClickListener {
|
||||
showConfetti(false)
|
||||
store.dispatch(OnboardingWalletAction.FinishOnboarding)
|
||||
}
|
||||
|
||||
animator.showSuccess {
|
||||
flCardsContainer.hide()
|
||||
imvCardBackground.hide()
|
||||
vConfetti.lavConfetti.show()
|
||||
vConfetti.lavConfetti.playAnimation()
|
||||
showConfetti(true)
|
||||
imvSuccess.alpha = 0f
|
||||
imvSuccess.show()
|
||||
imvSuccess.animate()?.alpha(1f)?.duration = 400
|
||||
}
|
||||
}
|
||||
|
||||
internal fun showConfetti(show: Boolean) = with(binding.vConfetti) {
|
||||
lavConfetti.show(show)
|
||||
|
||||
if (show) {
|
||||
lavConfetti.playAnimation()
|
||||
} else {
|
||||
lavConfetti.cancelAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleOnBackPressed() {
|
||||
store.dispatch(OnboardingWalletAction.OnBackPressed)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toTopOf="@+id/fl_scan_card_container"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btn_container"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
android:layout_marginTop="10dp"
|
||||
android:layout_marginEnd="64dp"
|
||||
android:minLines="3"
|
||||
app:layout_constraintBottom_toTopOf="@+id/fl_scan_card_container"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btn_container"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_header"
|
||||
|
|
@ -55,14 +55,14 @@
|
|||
android:textStyle="bold"
|
||||
android:visibility="gone"
|
||||
app:buttonTint="@color/accent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/fl_scan_card_container"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btn_container"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/linearLayoutCompat"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fl_scan_card_container"
|
||||
android:id="@+id/btn_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="90dp"
|
||||
|
|
@ -75,7 +75,7 @@
|
|||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_main_action"
|
||||
style="@style/OnboardingButton"
|
||||
android:text="@string/home_button_scan" />
|
||||
tools:text="@string/home_button_scan" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_main_action"
|
||||
android:id="@+id/btn_wallet_main_action"
|
||||
style="@style/OnboardingButton"
|
||||
android:layout_width="204dp"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
tools:text="Main Action" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_alternative_action"
|
||||
android:id="@+id/btn_wallet_alternative_action"
|
||||
style="@style/OnboardingButton.Borderless"
|
||||
android:layout_width="204dp"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
android:layout_marginBottom="@dimen/home_bottom_llCompat_margin_bottom"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toTopOf="@+id/fl_scan_card_container"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btn_container"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
android:layout_marginTop="@dimen/home_bottom_tv_body_margin_top"
|
||||
android:layout_marginEnd="@dimen/home_bottom_tv_body_margin_end"
|
||||
android:minLines="3"
|
||||
app:layout_constraintBottom_toTopOf="@+id/fl_scan_card_container"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btn_container"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_header"
|
||||
|
|
@ -55,14 +55,14 @@
|
|||
android:textStyle="bold"
|
||||
android:visibility="gone"
|
||||
app:buttonTint="@color/accent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/fl_scan_card_container"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btn_container"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/linearLayoutCompat"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fl_scan_card_container"
|
||||
android:id="@+id/btn_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/home_bottom_fl_scan_card_container_margin_bottom"
|
||||
|
|
@ -75,7 +75,7 @@
|
|||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_main_action"
|
||||
style="@style/OnboardingButton"
|
||||
android:text="@string/home_button_scan" />
|
||||
tools:text="@string/home_button_scan" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
|
|
|
|||
|
|
@ -32,4 +32,9 @@
|
|||
layout="@layout/layout_onboarding_saltpay_verify_identity_in_progress"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
android:id="@+id/claim"
|
||||
layout="@layout/layout_onboarding_main"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -142,4 +142,11 @@
|
|||
<string name="onboarding_saltpay_button_backup_origin">Tap the SaltPay card</string>
|
||||
<string name="onboarding_saltpay_title_backup_card">Tap the Tangem card</string>
|
||||
<string name="onboarding_chat_button_title">Support</string>
|
||||
<string name="onboarding_navbar_claim">Getting started</string>
|
||||
<string name="onboarding_title_claim">Claim %s</string>
|
||||
<string name="onboarding_subtitle_claim">To get started, simply claim wxDAI to your wallet</string>
|
||||
<string name="onboarding_button_claim">Claim</string>
|
||||
<string name="onboarding_subtitle_success_claim">Congratulations! Your first payment crypto card has been activated</string>
|
||||
<string name="onboarding_title_claim_progress">Claiming</string>
|
||||
<string name="onboarding_subtitle_claim_progress">It will take a few seconds</string>
|
||||
</resources>
|
||||
|
|
@ -142,4 +142,11 @@
|
|||
<string name="onboarding_saltpay_button_backup_origin">Tap the SaltPay card</string>
|
||||
<string name="onboarding_saltpay_title_backup_card">Tap the Tangem card</string>
|
||||
<string name="onboarding_chat_button_title">Support</string>
|
||||
<string name="onboarding_navbar_claim">Getting started</string>
|
||||
<string name="onboarding_title_claim">Claim %s</string>
|
||||
<string name="onboarding_subtitle_claim">To get started, simply claim wxDAI to your wallet</string>
|
||||
<string name="onboarding_button_claim">Claim</string>
|
||||
<string name="onboarding_subtitle_success_claim">Congratulations! Your first payment crypto card has been activated</string>
|
||||
<string name="onboarding_title_claim_progress">Claiming</string>
|
||||
<string name="onboarding_subtitle_claim_progress">It will take a few seconds</string>
|
||||
</resources>
|
||||
|
|
@ -142,4 +142,11 @@
|
|||
<string name="onboarding_saltpay_button_backup_origin">Tap the SaltPay card</string>
|
||||
<string name="onboarding_saltpay_title_backup_card">Tap the Tangem card</string>
|
||||
<string name="onboarding_chat_button_title">Support</string>
|
||||
<string name="onboarding_navbar_claim">Getting started</string>
|
||||
<string name="onboarding_title_claim">Claim %s</string>
|
||||
<string name="onboarding_subtitle_claim">To get started, simply claim wxDAI to your wallet</string>
|
||||
<string name="onboarding_button_claim">Claim</string>
|
||||
<string name="onboarding_subtitle_success_claim">Congratulations! Your first payment crypto card has been activated</string>
|
||||
<string name="onboarding_title_claim_progress">Claiming</string>
|
||||
<string name="onboarding_subtitle_claim_progress">It will take a few seconds</string>
|
||||
</resources>
|
||||
|
|
@ -140,4 +140,11 @@
|
|||
<string name="onboarding_saltpay_button_backup_origin">Приложите SaltPay карту</string>
|
||||
<string name="onboarding_saltpay_title_backup_card">Приложите Tangem карту</string>
|
||||
<string name="onboarding_chat_button_title">Чат</string>
|
||||
<string name="onboarding_navbar_claim">Начало работы</string>
|
||||
<string name="onboarding_title_claim">Запросить %s</string>
|
||||
<string name="onboarding_subtitle_claim">Для начала работы просто запросите начисление xDai на свой кошелек</string>
|
||||
<string name="onboarding_button_claim">Запросить</string>
|
||||
<string name="onboarding_subtitle_success_claim">Поздравляем! Ваша платежная крипто карта теперь активирована!</string>
|
||||
<string name="onboarding_title_claim_progress">Запрашивается</string>
|
||||
<string name="onboarding_subtitle_claim_progress">Это займет несколько секунд</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -142,4 +142,11 @@
|
|||
<string name="onboarding_saltpay_button_backup_origin">Tap the SaltPay card</string>
|
||||
<string name="onboarding_saltpay_title_backup_card">Tap the Tangem card</string>
|
||||
<string name="onboarding_chat_button_title">Support</string>
|
||||
<string name="onboarding_navbar_claim">Getting started</string>
|
||||
<string name="onboarding_title_claim">Claim %s</string>
|
||||
<string name="onboarding_subtitle_claim">To get started, simply claim wxDAI to your wallet</string>
|
||||
<string name="onboarding_button_claim">Claim</string>
|
||||
<string name="onboarding_subtitle_success_claim">Congratulations! Your first payment crypto card has been activated</string>
|
||||
<string name="onboarding_title_claim_progress">Claiming</string>
|
||||
<string name="onboarding_subtitle_claim_progress">It will take a few seconds</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ ext.versions = [
|
|||
build_gradle : '7.1.3',
|
||||
tangem_card_sdk : 'develop-165',
|
||||
// tangem_card_sdk : '0.0.1',
|
||||
tangem_blockchain_sdk: 'develop-129',
|
||||
tangem_blockchain_sdk: 'develop-130',
|
||||
// tangem_blockchain_sdk: '0.0.1',
|
||||
]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue