Updated on 2026-08-14

This commit is contained in:
Tangem 2024-04-16 15:14:23 +01:00
commit 48f20925f6
53 changed files with 541 additions and 76 deletions

View file

@ -7,6 +7,7 @@ import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.wallets.legacy.asLockable
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.dispatchWithMain
import kotlinx.coroutines.*
import timber.log.Timber
import kotlin.time.Duration
@ -103,12 +104,14 @@ internal class LockUserWalletsTimer(
|- Millis passed: ${currentTime - startTime}
""".trimIndent(),
)
userWalletsListManager.lock()
if (preferencesStorage.wasApplicationStopped) {
preferencesStorage.shouldOpenWelcomeScreenOnResume = true
} else {
store.dispatchOnMain(NavigationAction.PopBackTo(AppScreen.Welcome))
store.dispatchWithMain(NavigationAction.PopBackTo(AppScreen.Welcome))
}
userWalletsListManager.lock()
}
}
}

View file

@ -19,12 +19,14 @@ import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.WindowCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import arrow.core.getOrElse
import by.kirich1409.viewbindingdelegate.viewBinding
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.deeplink.DeepLinksRegistry
import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
@ -35,10 +37,13 @@ import com.tangem.data.card.sdk.CardSdkLifecycleObserver
import com.tangem.domain.apptheme.model.AppThemeMode
import com.tangem.domain.card.ScanCardUseCase
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.legacy.UserWalletsListManagerFeatureToggles
import com.tangem.domain.wallets.legacy.asLockable
import com.tangem.feature.qrscanning.QrScanningRouter
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
import com.tangem.features.managetokens.navigation.ManageTokensUi
import com.tangem.features.send.api.navigation.SendRouter
import com.tangem.features.tester.api.TesterRouter
@ -95,6 +100,7 @@ val userWalletsListManagerSafe: UserWalletsListManager?
val userWalletsListManager: UserWalletsListManager
get() = userWalletsListManagerSafe!!
@Suppress("LargeClass")
@AndroidEntryPoint
class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbackHolder {
@ -141,6 +147,15 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
@Inject
lateinit var userWalletsListManagerFeatureToggles: UserWalletsListManagerFeatureToggles
@Inject
lateinit var getPolkadotCheckHasResetUseCase: GetPolkadotCheckHasResetUseCase
@Inject
lateinit var getPolkadotCheckHasImmortalUseCase: GetPolkadotCheckHasImmortalUseCase
@Inject
lateinit var analyticsEventsHandler: AnalyticsEventHandler
internal val viewModel: MainViewModel by viewModels()
private lateinit var appThemeModeFlow: SharedFlow<AppThemeMode?>
@ -168,6 +183,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
checkForNotificationPermission()
observeStateUpdates()
observePolkadotAccountHealthCheck()
if (intent != null) {
deepLinksRegistry.launch(intent)
@ -457,4 +473,25 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), 0)
}
}
private fun observePolkadotAccountHealthCheck() {
lifecycleScope.launch {
getPolkadotCheckHasResetUseCase()
.flowWithLifecycle(lifecycle, minActiveState = Lifecycle.State.CREATED)
.distinctUntilChanged()
.collect {
analyticsEventsHandler.send(WalletScreenAnalyticsEvent.Token.PolkadotAccountReset(it.second))
}
}
lifecycleScope.launch {
getPolkadotCheckHasImmortalUseCase()
.flowWithLifecycle(lifecycle, minActiveState = Lifecycle.State.CREATED)
.distinctUntilChanged()
.collect {
analyticsEventsHandler.send(
WalletScreenAnalyticsEvent.Token.PolkadotImmortalTransactions(it.second),
)
}
}
}
}

View file

@ -46,7 +46,7 @@ class DialogManager : StoreSubscriber<GlobalState> {
dialog = when (state.dialog) {
is AppDialog.SimpleOkDialogRes -> SimpleOkDialog.create(state.dialog, context)
is StateDialog.ScanFailsDialog -> ScanFailsDialog.create(context)
is StateDialog.ScanFailsDialog -> ScanFailsDialog.create(context, state.dialog.source)
is AppDialog.AddressInfoDialog -> AddressInfoBottomSheetDialog(state.dialog, context)
is AppDialog.TestActionsDialog -> TestActionsBottomSheetDialog(state.dialog, context)
is AppDialog.RussianCardholdersWarningDialog -> RussianCardholdersWarningBottomSheetDialog(

View file

@ -2,6 +2,7 @@ package com.tangem.tap.common.redux.global
import com.tangem.blockchain.common.WalletManager
import com.tangem.common.CompletionResult
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.navigation.StateDialog
import com.tangem.datasource.config.ConfigManager
import com.tangem.datasource.config.models.ChatConfig
@ -51,7 +52,11 @@ sealed class GlobalAction : Action {
}
object ScanFailsCounter {
data class ChooseBehavior(val result: CompletionResult<ScanResponse>) : GlobalAction()
data class ChooseBehavior(
val result: CompletionResult<ScanResponse>,
val analyticsSource: AnalyticsParam.ScreensSources,
) : GlobalAction()
object Reset : GlobalAction()
object Increment : GlobalAction()
}

View file

@ -4,6 +4,7 @@ import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.common.extensions.guard
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import com.tangem.core.navigation.StateDialog
import com.tangem.datasource.config.models.Config
@ -54,14 +55,7 @@ private fun handleAction(action: Action, appState: () -> AppState?) {
when (action.result) {
is CompletionResult.Success -> store.dispatch(GlobalAction.ScanFailsCounter.Reset)
is CompletionResult.Failure -> {
if (action.result.error is TangemSdkError.UserCancelled) {
store.dispatch(GlobalAction.ScanFailsCounter.Increment)
if (store.state.globalState.scanCardFailsCounter >= 2) {
store.dispatchDialogShow(StateDialog.ScanFailsDialog)
}
} else {
store.dispatch(GlobalAction.ScanFailsCounter.Reset)
}
handleFailureChooseBehaviour(action.result, action.analyticsSource)
}
}
}
@ -184,6 +178,26 @@ private fun handleAction(action: Action, appState: () -> AppState?) {
}
}
private fun handleFailureChooseBehaviour(
result: CompletionResult.Failure<ScanResponse>,
analyticsSource: AnalyticsParam.ScreensSources,
) {
if (result.error is TangemSdkError.UserCancelled) {
store.dispatch(GlobalAction.ScanFailsCounter.Increment)
if (store.state.globalState.scanCardFailsCounter >= 2) {
val scanFailsSource = when (analyticsSource) {
is AnalyticsParam.ScreensSources.SignIn -> StateDialog.ScanFailsSource.SIGN_IN
is AnalyticsParam.ScreensSources.Settings -> StateDialog.ScanFailsSource.SETTINGS
is AnalyticsParam.ScreensSources.Intro -> StateDialog.ScanFailsSource.INTRO
else -> StateDialog.ScanFailsSource.MAIN
}
store.dispatchDialogShow(StateDialog.ScanFailsDialog(scanFailsSource))
}
} else {
store.dispatch(GlobalAction.ScanFailsCounter.Reset)
}
}
private fun restoreAppCurrency() {
scope.launch {
val currency = store.inject(DaggerGraphState::appCurrencyRepository)

View file

@ -4,7 +4,9 @@ import android.content.Context
import androidx.appcompat.app.AlertDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import com.tangem.core.navigation.StateDialog
import com.tangem.tap.common.extensions.dispatchDialogHide
import com.tangem.tap.common.feedback.ScanFailsEmail
import com.tangem.tap.common.redux.global.GlobalAction
@ -15,12 +17,18 @@ import com.tangem.wallet.R
[REDACTED_AUTHOR]
*/
object ScanFailsDialog {
fun create(context: Context): AlertDialog {
fun create(context: Context, source: StateDialog.ScanFailsSource): AlertDialog {
return MaterialAlertDialogBuilder(context, R.style.CustomMaterialDialog).apply {
setTitle(context.getString(R.string.common_warning))
setMessage(R.string.alert_troubleshooting_scan_card_title)
setPositiveButton(R.string.alert_button_request_support) { _, _ ->
Analytics.send(Basic.ButtonSupport())
val sourceAnalytics = when (source) {
StateDialog.ScanFailsSource.MAIN -> AnalyticsParam.ScreensSources.Main
StateDialog.ScanFailsSource.SIGN_IN -> AnalyticsParam.ScreensSources.SignIn
StateDialog.ScanFailsSource.SETTINGS -> AnalyticsParam.ScreensSources.Settings
StateDialog.ScanFailsSource.INTRO -> AnalyticsParam.ScreensSources.Intro
}
Analytics.send(Basic.ButtonSupport(sourceAnalytics))
store.dispatch(GlobalAction.SendEmail(ScanFailsEmail()))
}
setNeutralButton(R.string.common_cancel) { _, _ -> }

View file

@ -4,6 +4,9 @@ import android.content.Context
import com.tangem.domain.card.ScanCardUseCase
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
import com.tangem.domain.tokens.GetPolkadotCheckHasResetUseCase
import com.tangem.domain.tokens.repository.PolkadotAccountHealthCheckRepository
import com.tangem.tap.domain.TangemSdkManager
import com.tangem.tap.domain.scanCard.repository.DefaultScanCardRepository
import com.tangem.tap.network.exchangeServices.DefaultRampManager
@ -57,4 +60,20 @@ internal object ActivityModule {
fun provideActivityDelayedWorkCoroutineScope(): CoroutineScope {
return CoroutineScope(SupervisorJob() + Dispatchers.IO)
}
@Provides
@Singleton
fun provideGetPolkadotCheckHasResetUseCase(
polkadotAccountHealthCheckRepository: PolkadotAccountHealthCheckRepository,
): GetPolkadotCheckHasResetUseCase {
return GetPolkadotCheckHasResetUseCase(polkadotAccountHealthCheckRepository)
}
@Provides
@Singleton
fun provideGetPolkadotCheckHasImmortalUseCase(
polkadotAccountHealthCheckRepository: PolkadotAccountHealthCheckRepository,
): GetPolkadotCheckHasImmortalUseCase {
return GetPolkadotCheckHasImmortalUseCase(polkadotAccountHealthCheckRepository)
}
}

View file

@ -343,4 +343,12 @@ internal object TokensDomainModule {
): IsAmountSubtractAvailableUseCase {
return IsAmountSubtractAvailableUseCase(currenciesRepository, dispatchers)
}
@Provides
@ViewModelScoped
fun provideRunPolkadotAccountHealthCheckUseCase(
repository: PolkadotAccountHealthCheckRepository,
): RunPolkadotAccountHealthCheckUseCase {
return RunPolkadotAccountHealthCheckUseCase(repository)
}
}

View file

@ -2,7 +2,7 @@ package com.tangem.tap.domain.scanCard
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemError
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.domain.card.ScanCardProcessor
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.tap.common.extensions.inject
@ -27,7 +27,7 @@ internal class DefaultScanCardProcessor : ScanCardProcessor {
@Suppress("LongParameterList")
override suspend fun scan(
analyticsEvent: AnalyticsEvent?,
analyticsSource: AnalyticsParam.ScreensSources,
cardId: String?,
onProgressStateChange: suspend (showProgress: Boolean) -> Unit,
onWalletNotCreated: suspend () -> Unit,
@ -37,7 +37,7 @@ internal class DefaultScanCardProcessor : ScanCardProcessor {
) {
if (isNewCardScanningEnabled) {
UseCaseScanProcessor.scan(
analyticsEvent,
analyticsSource,
cardId,
onProgressStateChange,
onWalletNotCreated,
@ -47,7 +47,7 @@ internal class DefaultScanCardProcessor : ScanCardProcessor {
)
} else {
LegacyScanProcessor.scan(
analyticsEvent,
analyticsSource,
cardId,
onProgressStateChange,
onWalletNotCreated,

View file

@ -7,6 +7,8 @@ import com.tangem.common.doOnFailure
import com.tangem.common.doOnSuccess
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.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.common.TapWorkarounds.canSkipBackup
@ -45,7 +47,7 @@ internal object LegacyScanProcessor {
@Suppress("LongParameterList")
suspend fun scan(
analyticsEvent: AnalyticsEvent?,
analyticsSource: AnalyticsParam.ScreensSources,
cardId: String?,
onProgressStateChange: suspend (showProgress: Boolean) -> Unit,
onWalletNotCreated: suspend () -> Unit,
@ -59,7 +61,8 @@ internal object LegacyScanProcessor {
val result = tangemSdkManager.scanProduct(cardId)
store.dispatchOnMain(GlobalAction.ScanFailsCounter.ChooseBehavior(result))
val analyticsEvent = Basic.CardWasScanned(analyticsSource)
store.dispatchOnMain(GlobalAction.ScanFailsCounter.ChooseBehavior(result, analyticsSource))
result
.doOnFailure { error ->

View file

@ -4,7 +4,7 @@ import arrow.fx.coroutines.resourceScope
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemError
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.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
@ -44,7 +44,7 @@ internal object UseCaseScanProcessor {
@Suppress("LongParameterList")
suspend fun scan(
analyticsEvent: AnalyticsEvent?,
analyticsSource: AnalyticsParam.ScreensSources,
cardId: String?,
onProgressStateChange: suspend (showProgress: Boolean) -> Unit,
onWalletNotCreated: suspend () -> Unit,
@ -55,9 +55,7 @@ internal object UseCaseScanProcessor {
val scanCardUseCase = store.inject(DaggerGraphState::scanCardUseCase)
val chains = buildList {
add(FailedScansCounterChain(UseCaseScanProcessor::showMaxUnsuccessfulScansReachedDialog))
if (analyticsEvent != null) {
add(AnalyticsChain(analyticsEvent))
}
add(AnalyticsChain(Basic.CardWasScanned(analyticsSource)))
add(DisclaimerChain(store, disclaimerWillShow))
add(CheckForOnboardingChain(store, store.state.globalState.tapWalletManager))
}

View file

@ -81,6 +81,10 @@ internal class BiometricUserWalletsListManager(
state.update { State() }
}
override fun isLockable(): Boolean {
return true
}
override suspend fun select(userWalletId: UserWalletId): CompletionResult<UserWallet> = catching {
if (state.value.selectedUserWalletId == userWalletId) {
return@catching findSelectedUserWallet()!!

View file

@ -118,6 +118,10 @@ internal class GeneralUserWalletsListManager(
}
}
override fun isLockable(): Boolean {
return implementation.value.isLockable()
}
private fun subscribeOnCurrentManager() {
appPreferencesStore.get(key = PreferencesKeys.SAVE_USER_WALLETS_KEY, default = false)
.distinctUntilChanged()

View file

@ -85,6 +85,10 @@ internal class RuntimeUserWalletsListManager : UserWalletsListManager {
state.value.userWallet ?: walletNotFound()
}
override fun isLockable(): Boolean {
return false
}
private fun saveInternal(userWallet: UserWallet): CompletionResult<Unit> = catching {
state.update { prevState ->
prevState.copy(

View file

@ -7,7 +7,6 @@ import com.tangem.common.core.TangemSdkError
import com.tangem.common.core.UserCodeRequestPolicy
import com.tangem.common.extensions.guard
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.Basic
import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.extensions.TextReference
@ -580,7 +579,7 @@ class DetailsMiddleware {
)
store.inject(DaggerGraphState::scanCardProcessor).scan(
analyticsEvent = Basic.CardWasScanned(CoreAnalyticsParam.ScannedFrom.MyWallets),
analyticsSource = CoreAnalyticsParam.ScreensSources.Settings,
onWalletNotCreated = {
// No need to rollback policy, continue with the policy set before the card scan
store.dispatchWithMain(DetailsAction.ScanAndSaveUserWallet.Success)

View file

@ -4,6 +4,7 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import com.tangem.common.extensions.guard
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
@ -146,7 +147,7 @@ internal class DetailsViewModel(
}
private fun sendFeedback() {
Analytics.send(Basic.ButtonSupport())
Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Settings))
if (feedbackManagerFeatureToggles.isLocalLogsEnabled) {
mainScope.launch {
val email = getSupportFeedbackEmailUseCase()

View file

@ -1,8 +1,5 @@
package com.tangem.tap.features.home.redux
import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import kotlinx.coroutines.CoroutineScope
import org.rekotlin.Action
@ -16,11 +13,9 @@ sealed class HomeAction : Action {
/**
* Action for scanning card
*
* @property analyticsEvent analytics event
* @property scope lifecycle scope. It will be canceled when lifecycle-aware component is destroyed
*/
data class ReadCard(
val analyticsEvent: AnalyticsEvent? = Basic.CardWasScanned(AnalyticsParam.ScannedFrom.Introduction),
val scope: CoroutineScope,
) : HomeAction()

View file

@ -5,7 +5,7 @@ import com.tangem.common.doOnResult
import com.tangem.common.doOnSuccess
import com.tangem.common.extensions.guard
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.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
@ -60,7 +60,7 @@ private fun handleHomeAction(action: Action) {
}
is HomeAction.ReadCard -> {
action.scope.launch {
readCard(action.analyticsEvent)
readCard()
}
}
is HomeAction.GoToShop -> {
@ -76,13 +76,13 @@ private fun handleHomeAction(action: Action) {
}
}
private suspend fun readCard(analyticsEvent: AnalyticsEvent?) {
private suspend fun readCard() {
store.inject(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy(
isBiometricsRequestPolicy = preferencesStorage.shouldSaveAccessCodes,
)
store.inject(DaggerGraphState::scanCardProcessor).scan(
analyticsEvent = analyticsEvent,
analyticsSource = AnalyticsParam.ScreensSources.Intro,
onProgressStateChange = { showProgress ->
if (showProgress) {
store.dispatch(HomeAction.ScanInProgress(scanInProgress = true))

View file

@ -17,6 +17,7 @@ import com.tangem.domain.userwallets.UserWalletIdBuilder
import com.tangem.tap.*
import com.tangem.tap.common.analytics.converters.ParamCardCurrencyConverter
import com.tangem.tap.common.extensions.*
import com.tangem.tap.features.demo.DemoHelper
import com.tangem.tap.features.saveWallet.redux.SaveWalletAction
import com.tangem.tap.proxy.redux.DaggerGraphState
import kotlinx.coroutines.delay
@ -42,7 +43,8 @@ object OnboardingHelper {
response.cardTypesResolver.isWallet2() || response.cardTypesResolver.isShibaWallet() -> {
val emptyWallets = response.card.wallets.isEmpty()
val activationInProgress = onboardingManager?.isActivationInProgress(cardId)
val isNoBackup = response.card.backupStatus == CardDTO.BackupStatus.NoBackup
val isNoBackup = response.card.backupStatus == CardDTO.BackupStatus.NoBackup &&
!DemoHelper.isDemoCard(response)
emptyWallets || activationInProgress == true || isNoBackup
}

View file

@ -5,6 +5,7 @@ import android.view.MenuInflater
import android.view.MenuItem
import androidx.core.view.MenuProvider
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import com.tangem.tap.common.feedback.SupportInfo
import com.tangem.tap.common.redux.global.GlobalAction
@ -21,7 +22,7 @@ class OnboardingMenuProvider : MenuProvider {
override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) {
R.id.menu_item_chat_support -> {
Analytics.send(Basic.ButtonSupport())
Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Intro))
// changed on email support [REDACTED_TASK_KEY]
store.dispatch(GlobalAction.SendEmail(SupportInfo()))
true

View file

@ -22,6 +22,7 @@ import com.tangem.common.CardIdFormatter
import com.tangem.common.CompletionResult
import com.tangem.common.core.CardIdDisplayFormat
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import com.tangem.core.ui.extensions.setStatusBarColor
import com.tangem.domain.common.util.cardTypesResolver
@ -502,7 +503,7 @@ class OnboardingWalletFragment :
private fun makeSeedPhraseRouter(): SeedPhraseRouter = SeedPhraseRouter(
onBack = ::legacyOnBackHandler,
onOpenChat = {
Analytics.send(Basic.ButtonSupport())
Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Intro))
// changed on email support [REDACTED_TASK_KEY]
store.dispatch(GlobalAction.SendEmail(SupportInfo()))
},

View file

@ -4,6 +4,7 @@ import android.app.Dialog
import android.content.Context
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import com.tangem.tap.common.extensions.dispatchDialogHide
import com.tangem.tap.common.feedback.SupportInfo
@ -21,7 +22,7 @@ object WalletActivationErrorDialog {
setPositiveButton(R.string.common_ok) { _, _ -> dialog.onConfirm() }
setNegativeButton(R.string.common_support) { _, _ ->
// changed on email support [REDACTED_TASK_KEY]
Analytics.send(Basic.ButtonSupport())
Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Intro))
store.dispatch(GlobalAction.SendEmail(SupportInfo()))
}
setOnDismissListener { store.dispatchDialogHide() }

View file

@ -8,7 +8,6 @@ import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
import com.tangem.domain.userwallets.UserWalletBuilder
import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.domain.wallets.legacy.isLockable
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.tap.*
import com.tangem.tap.common.analytics.events.AnalyticsParam
@ -209,7 +208,7 @@ internal class SaveWalletMiddleware {
}
private suspend fun provideLockableUserWalletsListManagerIfNot() {
if (store.state.globalState.userWalletsListManager?.isLockable == true) return
if (store.state.globalState.userWalletsListManager?.isLockable() == true) return
val context = foregroundActivityObserver.foregroundActivity?.applicationContext.guard {
val error = IllegalStateException("No activities in foreground")

View file

@ -3,6 +3,7 @@ package com.tangem.tap.features.send.ui.dialogs
import android.content.Context
import androidx.appcompat.app.AlertDialog
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import com.tangem.tap.common.feedback.SendTransactionFailedEmail
import com.tangem.tap.common.redux.global.GlobalAction
@ -21,7 +22,7 @@ object RequestFeeErrorDialog {
setTitle(R.string.common_fee_error)
setMessage(context.getString(R.string.alert_failed_to_send_transaction_message, errorMessage))
setNegativeButton(R.string.details_row_title_contact_to_support) { _, _ ->
Analytics.send(Basic.ButtonSupport())
Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Send))
store.dispatch(GlobalAction.SendEmail(SendTransactionFailedEmail(errorMessage)))
}
setPositiveButton(R.string.common_retry) { _, _ -> dialog.onRetry() }

View file

@ -6,6 +6,7 @@ import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.BlockchainSdkError
import com.tangem.common.module.ModuleMessageConverter
import com.tangem.core.analytics.Analytics
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import com.tangem.sdk.extensions.localizedDescription
import com.tangem.tap.common.extensions.stripZeroPlainString
@ -33,7 +34,7 @@ object SendTransactionFailsDialog {
setTitle(R.string.alert_failed_to_send_transaction_title)
setMessage(context.getString(R.string.alert_failed_to_send_transaction_message, errorMessage))
setNeutralButton(R.string.details_row_title_contact_to_support) { _, _ ->
Analytics.send(Basic.ButtonSupport())
Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Send))
store.dispatch(GlobalAction.SendEmail(SendTransactionFailedEmail(errorMessage)))
}
setPositiveButton(R.string.common_cancel) { _, _ -> }

View file

@ -169,7 +169,7 @@ internal class WelcomeMiddleware {
isBiometricsRequestPolicy = preferencesStorage.shouldSaveAccessCodes,
)
store.inject(DaggerGraphState::scanCardProcessor).scan(
analyticsEvent = Basic.CardWasScanned(AnalyticsParam.ScannedFrom.SignIn),
analyticsSource = AnalyticsParam.ScreensSources.SignIn,
onSuccess = { scanResponse ->
scope.launch { onCardScanned(scanResponse) }
},