Updated on 2026-08-14
This commit is contained in:
commit
b45837c2f7
17 changed files with 146 additions and 24 deletions
|
|
@ -258,6 +258,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
onrampFeatureToggles = onrampFeatureToggles,
|
||||
environmentConfigStorage = environmentConfigStorage,
|
||||
onboardingV2FeatureToggles = onboardingV2FeatureToggles,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -159,6 +159,12 @@ class DialogManager : StoreSubscriber<GlobalState> {
|
|||
),
|
||||
context = context,
|
||||
)
|
||||
is AppDialog.WalletAlreadyWasUsedDialog -> WalletAlreadyWasUsedDialog.create(
|
||||
context = context,
|
||||
onOk = state.dialog.onOk,
|
||||
onSupport = state.dialog.onSupportClick,
|
||||
onCancel = state.dialog.onCancel,
|
||||
)
|
||||
is AppDialog.RemoveWalletDialog -> SimpleCancelableAlertDialog.create(
|
||||
title = context.getString(state.dialog.titleRes, state.dialog.currencyTitle),
|
||||
messageRes = state.dialog.messageRes,
|
||||
|
|
|
|||
|
|
@ -48,4 +48,10 @@ sealed class AppDialog : StateDialog {
|
|||
val messageRes: Int = R.string.token_details_unable_hide_alert_message
|
||||
val titleRes: Int = R.string.token_details_unable_hide_alert_title
|
||||
}
|
||||
|
||||
data class WalletAlreadyWasUsedDialog(
|
||||
val onOk: () -> Unit,
|
||||
val onSupportClick: () -> Unit,
|
||||
val onCancel: () -> Unit,
|
||||
) : AppDialog()
|
||||
}
|
||||
|
|
@ -9,18 +9,25 @@ import com.tangem.core.analytics.Analytics
|
|||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.domain.common.TapWorkarounds.canSkipBackup
|
||||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.domain.common.util.twinsIsTwinned
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
||||
import com.tangem.tap.common.analytics.paramsInterceptor.CardContextInterceptor
|
||||
import com.tangem.tap.common.extensions.*
|
||||
import com.tangem.tap.common.redux.AppDialog
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.features.disclaimer.createDisclaimer
|
||||
import com.tangem.tap.features.onboarding.OnboardingHelper
|
||||
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
|
||||
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsStep
|
||||
import com.tangem.tap.features.onboarding.products.wallet.redux.BackupStartedSource
|
||||
import com.tangem.tap.mainScope
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
|
|
@ -135,32 +142,79 @@ internal object LegacyScanProcessor {
|
|||
) {
|
||||
store.dispatchOnMain(TwinCardsAction.IfTwinsPrepareState(scanResponse))
|
||||
|
||||
if (OnboardingHelper.isOnboardingCase(scanResponse)) {
|
||||
Analytics.addContext(scanResponse)
|
||||
onWalletNotCreated()
|
||||
// must check skip backup using card canSkipBackup
|
||||
store.dispatchOnMain(
|
||||
GlobalAction.Onboarding.Start(
|
||||
scanResponse = scanResponse,
|
||||
source = BackupStartedSource.Onboarding,
|
||||
canSkipBackup = scanResponse.card.canSkipBackup,
|
||||
checkCardWasUsedInApp(
|
||||
scanResponse = scanResponse,
|
||||
onCancel = { mainScope.launch { onProgressStateChange.invoke(false) } },
|
||||
) {
|
||||
if (OnboardingHelper.isOnboardingCase(scanResponse)) {
|
||||
Analytics.addContext(scanResponse)
|
||||
onWalletNotCreated()
|
||||
// must check skip backup using card canSkipBackup
|
||||
store.dispatchOnMain(
|
||||
GlobalAction.Onboarding.Start(
|
||||
scanResponse = scanResponse,
|
||||
source = BackupStartedSource.Onboarding,
|
||||
canSkipBackup = scanResponse.card.canSkipBackup,
|
||||
),
|
||||
)
|
||||
val appScreen = OnboardingHelper.whereToNavigate(scanResponse)
|
||||
navigateTo(appScreen) { onProgressStateChange(it) }
|
||||
} else {
|
||||
Analytics.setContext(scanResponse)
|
||||
|
||||
val wasTwinsOnboardingShown =
|
||||
store.inject(DaggerGraphState::wasTwinsOnboardingShownUseCase).invokeSync()
|
||||
|
||||
if (scanResponse.twinsIsTwinned() && !wasTwinsOnboardingShown) {
|
||||
onWalletNotCreated()
|
||||
store.dispatchOnMain(TwinCardsAction.SetStepOfScreen(TwinCardsStep.WelcomeOnly(scanResponse)))
|
||||
navigateTo(AppRoute.OnboardingTwins) { onProgressStateChange(it) }
|
||||
} else {
|
||||
delay(DELAY_SDK_DIALOG_CLOSE)
|
||||
onSuccess(scanResponse)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if card has password and never login at this app
|
||||
* Show alert in this case
|
||||
*/
|
||||
private suspend fun checkCardWasUsedInApp(
|
||||
scanResponse: ScanResponse,
|
||||
onCancel: () -> Unit,
|
||||
onSuccess: suspend () -> Unit,
|
||||
) {
|
||||
val userWalletId = UserWalletIdBuilder.card(scanResponse.card).build()
|
||||
if (userWalletId == null) {
|
||||
onSuccess()
|
||||
return
|
||||
}
|
||||
val appPrefStoreStore = store.inject(DaggerGraphState::appPreferencesStore)
|
||||
val tokens = appPrefStoreStore.getObjectSyncOrNull<UserTokensResponse>(
|
||||
key = PreferencesKeys.getUserTokensKey(userWalletId.stringValue),
|
||||
)
|
||||
if (scanResponse.card.isAccessCodeSet && tokens == null) {
|
||||
store.dispatchDialogShow(
|
||||
AppDialog.WalletAlreadyWasUsedDialog(
|
||||
onOk = { mainScope.launch { onSuccess() } },
|
||||
onSupportClick = {
|
||||
val cardInfo =
|
||||
store.inject(DaggerGraphState::getCardInfoUseCase).invoke(scanResponse).getOrNull()
|
||||
?: error("CardInfo must be not null")
|
||||
|
||||
scope.launch {
|
||||
store.inject(DaggerGraphState::sendFeedbackEmailUseCase)
|
||||
.invoke(type = FeedbackEmailType.PreActivatedWallet(cardInfo))
|
||||
}
|
||||
onCancel()
|
||||
},
|
||||
onCancel = { onCancel() },
|
||||
),
|
||||
)
|
||||
val appScreen = OnboardingHelper.whereToNavigate(scanResponse)
|
||||
navigateTo(appScreen) { onProgressStateChange(it) }
|
||||
} else {
|
||||
Analytics.setContext(scanResponse)
|
||||
|
||||
val wasTwinsOnboardingShown = store.inject(DaggerGraphState::wasTwinsOnboardingShownUseCase).invokeSync()
|
||||
|
||||
if (scanResponse.twinsIsTwinned() && !wasTwinsOnboardingShown) {
|
||||
onWalletNotCreated()
|
||||
store.dispatchOnMain(TwinCardsAction.SetStepOfScreen(TwinCardsStep.WelcomeOnly(scanResponse)))
|
||||
navigateTo(AppRoute.OnboardingTwins) { onProgressStateChange(it) }
|
||||
} else {
|
||||
delay(DELAY_SDK_DIALOG_CLOSE)
|
||||
onSuccess(scanResponse)
|
||||
}
|
||||
onSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.ui.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
|
||||
object WalletAlreadyWasUsedDialog {
|
||||
|
||||
fun create(context: Context, onOk: () -> Unit, onCancel: () -> Unit, onSupport: () -> Unit): AlertDialog {
|
||||
return MaterialAlertDialogBuilder(context, R.style.CustomMaterialDialog).apply {
|
||||
setTitle(R.string.security_alert_title)
|
||||
setMessage(R.string.wallet_been_activated_message)
|
||||
setPositiveButton(R.string.this_is_my_wallet_title) { dialog, _ ->
|
||||
onOk()
|
||||
dialog.dismiss()
|
||||
}
|
||||
setNeutralButton(R.string.common_cancel) { dialog, _ ->
|
||||
onCancel()
|
||||
dialog.dismiss()
|
||||
}
|
||||
setNegativeButton(R.string.alert_button_request_support) { dialog, _ ->
|
||||
onSupport()
|
||||
dialog.dismiss()
|
||||
}
|
||||
setOnDismissListener {
|
||||
store.dispatch(GlobalAction.HideDialog)
|
||||
}
|
||||
}.create()
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ internal sealed interface WelcomeAction : Action {
|
|||
object ProceedWithCard : WelcomeAction {
|
||||
object Success : WelcomeAction
|
||||
data class Error(val error: TangemError) : WelcomeAction
|
||||
data class ChangeProgress(val showProgress: Boolean) : WelcomeAction
|
||||
}
|
||||
|
||||
data class ProceedWithIntent(val intent: Intent) : WelcomeAction
|
||||
|
|
|
|||
|
|
@ -197,6 +197,9 @@ internal class WelcomeMiddleware {
|
|||
}
|
||||
}
|
||||
},
|
||||
onProgressStateChange = {
|
||||
store.dispatchWithMain(WelcomeAction.ProceedWithCard.ChangeProgress(it))
|
||||
},
|
||||
onWalletNotCreated = {
|
||||
store.dispatchOnMain(WelcomeAction.ProceedWithCard.Success)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ internal object WelcomeReducer {
|
|||
error = action.error,
|
||||
isUnlockWithCardInProgress = false,
|
||||
)
|
||||
is WelcomeAction.ProceedWithCard.ChangeProgress -> state.copy(
|
||||
isUnlockWithCardInProgress = action.showProgress,
|
||||
)
|
||||
is WelcomeAction.ProceedWithBiometrics.Success -> state.copy(isUnlockWithBiometricsInProgress = false)
|
||||
is WelcomeAction.ProceedWithCard.Success -> state.copy(isUnlockWithCardInProgress = false)
|
||||
is WelcomeAction.CloseError -> state.copy(error = null)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.core.navigation.url.UrlOpener
|
|||
import com.tangem.datasource.connection.NetworkConnectionManager
|
||||
import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
|
||||
import com.tangem.datasource.local.config.issuers.IssuersConfigStorage
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
|
||||
import com.tangem.domain.apptheme.repository.AppThemeModeRepository
|
||||
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
|
||||
|
|
@ -71,4 +72,5 @@ data class DaggerGraphState(
|
|||
val onrampFeatureToggles: OnrampFeatureToggles? = null,
|
||||
val environmentConfigStorage: EnvironmentConfigStorage? = null,
|
||||
val onboardingV2FeatureToggles: OnboardingV2FeatureToggles? = null,
|
||||
val appPreferencesStore: AppPreferencesStore? = null,
|
||||
) : StateType
|
||||
|
|
@ -650,6 +650,7 @@
|
|||
<string name="scan_card_settings_button">Сканировать</string>
|
||||
<string name="scan_card_settings_message">Отсканируйте карту или кольцо, чтобы изменить ее настройки. Изменения затронут только ту карту или кольцо, которые вы отсканировали, и не повлияют на другие устройства, привязанные к вашему кошельку.</string>
|
||||
<string name="scan_card_settings_title">Приготовьте свой Tangem!</string>
|
||||
<string name="security_alert_title">Уведомление безопасности</string>
|
||||
<string name="send_additional_field_already_included">Уже содержится во введенном адресе</string>
|
||||
<string name="send_alert_fee_too_high_text">Сумма комиссии в %s раз превышает рекомендованную. Убедитесь, что указанная комиссия верна.</string>
|
||||
<string name="send_alert_fee_too_low_text">Вы указали комиссию ниже рекомендуемой, это может привести к задержке исполнения вашей транзакции. Продолжить?</string>
|
||||
|
|
@ -861,6 +862,7 @@
|
|||
<string name="swapping_to_title">Вы получите</string>
|
||||
<string name="swapping_token_list_title">Выберите токен</string>
|
||||
<string name="swapping_token_not_available">не доступен</string>
|
||||
<string name="this_is_my_wallet_title">Это мой кошелек</string>
|
||||
<string name="toast_balances_hidden">Балансы скрыты</string>
|
||||
<string name="toast_balances_shown">Балансы показаны</string>
|
||||
<string name="toast_undo">Отменить</string>
|
||||
|
|
@ -929,6 +931,7 @@
|
|||
<string name="user_wallet_list_unlock_all_with">Разблокировать все с %s</string>
|
||||
<string name="wallet_balance_blockchain_unreachable_try_later">Блокчейн недоступен. Попробуйте позже.</string>
|
||||
<string name="wallet_balance_missing_derivation">Отсканируйте карту или кольцо</string>
|
||||
<string name="wallet_been_activated_message">Этот кошелек уже был активирован ранее.\nЕсли это сделали не вы, свяжитесь со службой поддержки.\nTangem никогда не продает кошелек вместе с предустановленным кодом доступа.</string>
|
||||
<string name="wallet_connect_alert_sign_message">Запрос на подпись сообщения.\n\n%s</string>
|
||||
<string name="wallet_connect_bnb_sign_message">Dapp %1$s, запрос на\nподпись транзакции с BNB.\n\n%2$s</string>
|
||||
<string name="wallet_connect_bnb_trade_order_message">Торговый ордер на %1$s\nЦена: %2$s\nСумма к получению: %3$s\nСумма к оплате: %4$s</string>
|
||||
|
|
|
|||
|
|
@ -307,6 +307,7 @@
|
|||
<string name="feedback_preface_scan_failed">Please tell us what card or ring do you have</string>
|
||||
<string name="feedback_preface_support">Hi support team,</string>
|
||||
<string name="feedback_preface_tx_failed">Please tell us more about your issue. Every small detail can help.</string>
|
||||
<string name="feedback_subject_pre_activated_wallet">Previously activated wallet</string>
|
||||
<string name="feedback_subject_rate_negative">My suggestions</string>
|
||||
<string name="feedback_subject_scan_failed">Can\'t scan a card/ring</string>
|
||||
<string name="feedback_subject_support">Feedback</string>
|
||||
|
|
@ -648,6 +649,7 @@
|
|||
<string name="scan_card_settings_button">Scan card or ring</string>
|
||||
<string name="scan_card_settings_message">Scan the card or ring to change its settings. The changes will impact only the card or ring you\'ve scanned and will not affect other devices tied to your wallet.</string>
|
||||
<string name="scan_card_settings_title">Get your Tangem ready!</string>
|
||||
<string name="security_alert_title">Security Alert</string>
|
||||
<string name="send_additional_field_already_included">Already included in the entered address</string>
|
||||
<string name="send_alert_fee_too_high_text">Your commission amount is %s times higher than the recommended amount. Please review and adjust your custom settings.</string>
|
||||
<string name="send_alert_fee_too_low_text">You specified a commission below the recommended amount, which could cause a delay in your transaction. Continue?</string>
|
||||
|
|
@ -860,6 +862,7 @@
|
|||
<string name="swapping_to_title">You receive</string>
|
||||
<string name="swapping_token_list_title">Choose token</string>
|
||||
<string name="swapping_token_not_available">not available</string>
|
||||
<string name="this_is_my_wallet_title">This is my wallet</string>
|
||||
<string name="toast_balances_hidden">Balances hidden</string>
|
||||
<string name="toast_balances_shown">Balances shown</string>
|
||||
<string name="toast_undo">Undo</string>
|
||||
|
|
@ -928,6 +931,7 @@
|
|||
<string name="user_wallet_list_unlock_all_with">Unlock all with %s</string>
|
||||
<string name="wallet_balance_blockchain_unreachable_try_later">Blockchain is unreachable. Try later</string>
|
||||
<string name="wallet_balance_missing_derivation">Scan card or ring</string>
|
||||
<string name="wallet_been_activated_message">This wallet has already been activated earlier.\nIf it was done not by you please contact support.\nTangem never sells wallets along with the pre-generated access code.</string>
|
||||
<string name="wallet_connect_alert_sign_message">Requesting to sign a message.\n\n%s</string>
|
||||
<string name="wallet_connect_bnb_sign_message">Dapp %1$s, requesting to\nsign BNB transaction.\n\n%2$s</string>
|
||||
<string name="wallet_connect_bnb_trade_order_message">Trade order for %1$s\nPrice: %2$s\nAmount to receive: %3$s\nAmount to pay: %4$s</string>
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ class SendFeedbackEmailUseCase(
|
|||
return when (type) {
|
||||
is FeedbackEmailType.ScanningProblem,
|
||||
is FeedbackEmailType.CurrencyDescriptionError,
|
||||
is FeedbackEmailType.PreActivatedWallet,
|
||||
-> this
|
||||
is FeedbackEmailType.DirectUserRequest,
|
||||
is FeedbackEmailType.RateCanBeBetter,
|
||||
|
|
|
|||
|
|
@ -46,4 +46,6 @@ sealed interface FeedbackEmailType {
|
|||
data class CurrencyDescriptionError(val currencyId: String, val currencyName: String) : FeedbackEmailType {
|
||||
override val cardInfo: CardInfo? = null
|
||||
}
|
||||
|
||||
data class PreActivatedWallet(override val cardInfo: CardInfo) : FeedbackEmailType
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ internal class EmailMessageBodyResolver(
|
|||
is FeedbackEmailType.StakingProblem -> addStakingProblemBody(type)
|
||||
is FeedbackEmailType.SwapProblem -> addSwapProblemBody(type)
|
||||
is FeedbackEmailType.CurrencyDescriptionError -> addTokenInfo(type)
|
||||
is FeedbackEmailType.PreActivatedWallet -> addUserRequestBody(type.cardInfo)
|
||||
}
|
||||
|
||||
return build()
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ internal class EmailMessageTitleResolver(private val resources: Resources) {
|
|||
is FeedbackEmailType.StakingProblem,
|
||||
is FeedbackEmailType.SwapProblem,
|
||||
-> R.string.feedback_preface_tx_failed
|
||||
is FeedbackEmailType.PreActivatedWallet -> R.string.feedback_preface_support
|
||||
}
|
||||
.let(resources::getString)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ internal class EmailSubjectResolver(private val resources: Resources) {
|
|||
is FeedbackEmailType.StakingProblem,
|
||||
is FeedbackEmailType.SwapProblem,
|
||||
-> R.string.feedback_subject_tx_failed
|
||||
is FeedbackEmailType.PreActivatedWallet -> R.string.feedback_subject_pre_activated_wallet
|
||||
is FeedbackEmailType.CurrencyDescriptionError -> R.string.feedback_token_description_error
|
||||
}
|
||||
.let(resources::getString)
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ markdownComposeView = "0.5.4"
|
|||
# region Tangem
|
||||
tangemBlockchainSdk = "release-app_5.18-874"
|
||||
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||
tangemCardSdk = "release-app_5.18-409"
|
||||
tangemCardSdk = "release-app_5.18-413"
|
||||
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^
|
||||
tangemVico = "2.0.0-alpha.25-tangem17"
|
||||
#tangemVico = "0.0.1" # Keep it! - used for local builds ^
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue