Updated on 2026-08-14

This commit is contained in:
Tangem 2023-02-03 18:32:36 +08:00
parent 2ade5a1407
commit 645cf17efb
24 changed files with 612 additions and 112 deletions

View file

@ -27,6 +27,7 @@ class BasicEventsPreChecker {
BasicTopUpEventConverter().convert(converterData)?.let { Analytics.send(it) }
}
@Suppress("ComplexMethod")
private fun isReadyToSend(data: BasicEventsSourceData): Boolean {
val (scanResponse, walletState, biometricsWalletDataModels) = data
if (walletState.derivationsCheckIsScheduled) {
@ -69,13 +70,14 @@ class BasicEventsPreChecker {
return false
}
if (biometricsWalletDataModels.any {
val isCorrectStatus = biometricsWalletDataModels.any {
it.status is WalletDataModel.Loading ||
it.status is WalletDataModel.NoAccount ||
it.status is WalletDataModel.Unreachable ||
it.status is WalletDataModel.MissedDerivation ||
it.status.isErrorStatus
}) {
}
if (isCorrectStatus) {
Timber.d("FAILED: by status")
return false
}

View file

@ -20,7 +20,8 @@ class ShopOrderToEventConverter : Converter<Pair<Storefront.Checkout, ProductTyp
ProductType.WALLET_3_CARDS -> "3"
}
val amount = "${checkout.totalPriceV2.amount} ${checkout.totalPriceV2.currencyCode.name}"
val code = (checkout.discountApplications.edges.firstOrNull()?.node as? Storefront.DiscountCodeApplication)?.code
val code = (checkout.discountApplications.edges.firstOrNull()?.node as? Storefront.DiscountCodeApplication)
?.code
return Shop.Purchased(sku, count, amount, code)
}

View file

@ -148,27 +148,29 @@ object ScanCardProcessor {
store.dispatchOnMain(DisclaimerAction.SetDisclaimer(disclaimer))
if (disclaimer.isAccepted()) {
nextHandler((scanResponse))
} else scope.launch {
delay(DELAY_SDK_DIALOG_CLOSE)
disclaimerWillShow()
dispatchOnMain(
DisclaimerAction.Show(
fromScreen = AppScreen.Home,
callback = DisclaimerCallback(
onAccept = {
scope.launch(Dispatchers.Main) {
nextHandler(scanResponse)
}
},
onDismiss = {
scope.launch(Dispatchers.Main) {
onFailure(TangemSdkError.UserCancelled())
}
},
nextHandler(scanResponse)
} else {
scope.launch {
delay(DELAY_SDK_DIALOG_CLOSE)
disclaimerWillShow()
dispatchOnMain(
DisclaimerAction.Show(
fromScreen = AppScreen.Home,
callback = DisclaimerCallback(
onAccept = {
scope.launch(Dispatchers.Main) {
nextHandler(scanResponse)
}
},
onDismiss = {
scope.launch(Dispatchers.Main) {
onFailure(TangemSdkError.UserCancelled())
}
},
),
),
),
)
)
}
}
}

View file

@ -47,10 +47,10 @@ internal class DefaultTotalFiatBalanceCalculator : TotalFiatBalanceCalculator {
is WalletDataModel.VerifiedOnline,
is WalletDataModel.SameCurrencyTransactionInProgress,
is WalletDataModel.TransactionInProgress,
is WalletDataModel.NoAccount,
-> {
if (walletData.fiatRate == null) TotalFiatBalanceStatus.Error
else TotalFiatBalanceStatus.Loaded
is WalletDataModel.NoAccount -> if (walletData.fiatRate == null) {
TotalFiatBalanceStatus.Error
} else {
TotalFiatBalanceStatus.Loaded
}
is WalletDataModel.Unreachable,
is WalletDataModel.MissedDerivation,

View file

@ -113,7 +113,7 @@ private fun readCard(analyticsEvent: AnalyticsEvent?) = scope.launch {
private suspend fun navigateTo(appScreen: AppScreen) {
store.dispatchOnMain(NavigationAction.NavigateTo(appScreen))
delay(200)
delay(timeMillis = 200)
changeButtonState(ButtonState.ENABLED)
}

View file

@ -11,35 +11,33 @@ import com.tangem.tap.store
/**
[REDACTED_AUTHOR]
*/
class SaltPayExceptionHandler {
companion object {
fun handle(throwable: Throwable) {
when (throwable) {
is SaltPayActivationError -> {
val dialog = when (throwable) {
is SaltPayActivationError.NoGas -> SaltPayDialog.Activation.NoGas
is SaltPayActivationError.PutVisaCard -> SaltPayDialog.Activation.PutVisaCard
else -> SaltPayDialog.Activation.OnError(throwable)
object SaltPayExceptionHandler {
fun handle(throwable: Throwable) {
when (throwable) {
is SaltPayActivationError -> {
val dialog = when (throwable) {
is SaltPayActivationError.NoGas -> SaltPayDialog.Activation.NoGas
is SaltPayActivationError.PutVisaCard -> SaltPayDialog.Activation.PutVisaCard
else -> SaltPayDialog.Activation.OnError(throwable)
}
store.dispatchDialogShow(dialog)
}
is TangemSdkError -> {
when (throwable) {
is TangemSdkError.NetworkError -> {
val message = throwable.customMessage
store.dispatchDialogShow(AppDialog.SimpleOkErrorDialog(message))
}
store.dispatchDialogShow(dialog)
}
is TangemSdkError -> {
when (throwable) {
is TangemSdkError.NetworkError -> {
val message = (throwable).customMessage
store.dispatchDialogShow(AppDialog.SimpleOkErrorDialog(message))
}
else -> Unit
}
}
is BlockchainSdkError -> {
store.dispatchDialogShow(AppDialog.SimpleOkErrorDialog(throwable.customMessage))
}
else -> {
val message = throwable.localizedMessage ?: "SaltPay unknown error"
store.dispatchDialogShow(AppDialog.SimpleOkErrorDialog(message))
else -> Unit
}
}
is BlockchainSdkError -> {
store.dispatchDialogShow(AppDialog.SimpleOkErrorDialog(throwable.customMessage))
}
else -> {
val message = throwable.localizedMessage ?: "SaltPay unknown error"
store.dispatchDialogShow(AppDialog.SimpleOkErrorDialog(message))
}
}
}
}

View file

@ -11,17 +11,15 @@ import com.tangem.wallet.R
/**
[REDACTED_AUTHOR]
*/
class InterruptOnboardingDialog {
companion object {
fun create(context: Context, dialog: OnboardingDialog.InterruptOnboarding): Dialog {
return AlertDialog.Builder(context).apply {
setTitle(context.getString(R.string.onboarding_exit_alert_title))
setMessage(context.getString(R.string.onboarding_exit_alert_message))
setPositiveButton(R.string.common_ok) { _, _ -> dialog.onOk() }
setNegativeButton(R.string.common_cancel) { _, _ -> }
setOnDismissListener { store.dispatchDialogHide() }
setCancelable(false)
}.create()
}
object InterruptOnboardingDialog {
fun create(context: Context, dialog: OnboardingDialog.InterruptOnboarding): Dialog {
return AlertDialog.Builder(context).apply {
setTitle(context.getString(R.string.onboarding_exit_alert_title))
setMessage(context.getString(R.string.onboarding_exit_alert_message))
setPositiveButton(R.string.common_ok) { _, _ -> dialog.onOk() }
setNegativeButton(R.string.common_cancel) { _, _ -> }
setOnDismissListener { store.dispatchDialogHide() }
setCancelable(false)
}.create()
}
}

View file

@ -10,18 +10,16 @@ import com.tangem.wallet.R
/**
[REDACTED_AUTHOR]
*/
class PutVisaCardDialog {
companion object {
fun create(context: Context): Dialog {
return AlertDialog.Builder(context).apply {
setTitle(R.string.saltpay_error_empty_backup_title)
setMessage(R.string.saltpay_error_empty_backup_message)
setPositiveButton(R.string.common_ok) { _, _ -> }
setOnDismissListener {
store.dispatch(GlobalAction.HideDialog)
}
setCancelable(false)
}.create()
}
object PutVisaCardDialog {
fun create(context: Context): Dialog {
return AlertDialog.Builder(context).apply {
setTitle(R.string.saltpay_error_empty_backup_title)
setMessage(R.string.saltpay_error_empty_backup_message)
setPositiveButton(R.string.common_ok) { _, _ -> }
setOnDismissListener {
store.dispatch(GlobalAction.HideDialog)
}
setCancelable(false)
}.create()
}
}

View file

@ -48,8 +48,7 @@ sealed class SaltPayActivationError(
object FailedToGetFundsToClaim : SaltPayActivationError(subCode = 14)
object NoFundsToClaim : SaltPayActivationError(subCode = 15)
object ClaimTransactionFailed : SaltPayActivationError(subCode = 16)
object PutVisaCard : SaltPayActivationError(18)
object PutVisaCard : SaltPayActivationError(subCode = 18)
companion object {
const val EMPTY_MESSAGE = ""

View file

@ -29,7 +29,7 @@ class ShopFragment : BaseStoreFragment(R.layout.fragment_shop), StoreSubscriber<
private val binding: FragmentShopBinding by viewBinding(FragmentShopBinding::bind)
private var cardTranslationY = 70f
lateinit var keyboardObserver: KeyboardObserver
private lateinit var keyboardObserver: KeyboardObserver
override fun subscribeToStore() {
store.subscribe(this) { state ->

View file

@ -66,7 +66,6 @@ import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.rekotlin.Action
import org.rekotlin.DispatchFunction
import org.rekotlin.Middleware
import timber.log.Timber
import java.math.BigDecimal
@ -87,17 +86,17 @@ class WalletMiddleware {
)
}
val walletMiddleware: Middleware<AppState> = { dispatch, state ->
val walletMiddleware: Middleware<AppState> = { _, state ->
{ next ->
{ action ->
handleAction(state, action, dispatch)
handleAction(state, action)
next(action)
}
}
}
@Suppress("LongMethod", "ComplexMethod")
private fun handleAction(state: () -> AppState?, action: Action, dispatch: DispatchFunction) {
private fun handleAction(state: () -> AppState?, action: Action) {
if (DemoHelper.tryHandle(state, action)) return
val globalState = store.state.globalState
@ -203,7 +202,7 @@ class WalletMiddleware {
is WalletAction.Scan -> {
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
scope.launch {
delay(700)
delay(timeMillis = 700)
store.dispatchOnMain(HomeAction.ReadCard(action.onScanSuccessEvent))
}
}
@ -344,7 +343,7 @@ class WalletMiddleware {
.filter { store ->
store.walletsData.any { it.status is WalletDataModel.MissedDerivation }
}
.map { it.blockchainNetwork }
.map(WalletStoreModel::blockchainNetwork)
store.dispatchOnMain(WalletAction.MultiWallet.AddMissingDerivations(missedDerivations))
}

View file

@ -104,10 +104,12 @@ internal class WalletSelectorMiddleware {
updatedWalletStores: Map<UserWalletId, List<WalletStoreModel>>,
state: WalletSelectorState,
) {
if (updatedWalletStores.isNotEmpty()) scope.launch(Dispatchers.Default) {
val updatedWallets = state.wallets.updateWalletStoresAndCalculateFiatBalance(updatedWalletStores)
if (updatedWallets != state.wallets) {
store.dispatchOnMain(WalletSelectorAction.BalancesLoaded(updatedWallets))
if (updatedWalletStores.isNotEmpty()) {
scope.launch(Dispatchers.Default) {
val updatedWallets = state.wallets.updateWalletStoresAndCalculateFiatBalance(updatedWalletStores)
if (updatedWallets != state.wallets) {
store.dispatchOnMain(WalletSelectorAction.BalancesLoaded(updatedWallets))
}
}
}
}

View file

@ -228,10 +228,10 @@ private fun LoadingTokensInfo(isMultiCurrencyWallet: Boolean) {
@OptIn(ExperimentalComposeUiApi::class)
@Composable
private fun LoadedTokensInfo(
modifier: Modifier = Modifier,
balanceAmount: String,
tokensCount: Int?,
showWarning: Boolean,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier,