Updated on 2026-08-14

This commit is contained in:
Tangem 2023-01-19 15:09:30 +03:00
parent ae43a82d23
commit 1d3c107a93
8 changed files with 80 additions and 53 deletions

View file

@ -116,17 +116,12 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
super.onResume()
notificationsHandler = NotificationsHandler(binding.fragmentContainer)
navigateToInitialScreenIfNeeded()
intentHandler.handleBackgroundScan(intent)
intentHandler.handleSellCurrencyCallback(intent)
navigateToInitialScreenIfNeeded(intent)
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
intentHandler.handleBackgroundScan(intent)
intentHandler.handleSellCurrencyCallback(intent)
intentHandler.handleWalletConnectLink(intent)
intentHandler.handleIntent(intent, userWalletsListManager.hasSavedUserWallets)
}
override fun onStart() {
@ -192,29 +187,28 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
lockUserWalletsTimer?.restart()
}
private fun navigateToInitialScreenIfNeeded() {
private fun navigateToInitialScreenIfNeeded(intent: Intent?) {
val backStackIsEmpty = supportFragmentManager.backStackEntryCount == 0
val isNotScannedBefore = store.state.globalState.scanResponse == null
val isOnboardingServiceNotActive = store.state.globalState.onboardingState.onboardingStarted
val isShopNotOpened = store.state.shopState.total != null
when {
!backStackIsEmpty && isNotScannedBefore && isOnboardingServiceNotActive && isShopNotOpened -> {
navigateToInitialScreen()
navigateToInitialScreen(intent)
}
backStackIsEmpty -> {
navigateToInitialScreen()
navigateToInitialScreen(intent)
}
}
}
private fun navigateToInitialScreen() {
private fun navigateToInitialScreen(intent: Intent?) {
if (userWalletsListManager.hasSavedUserWallets) {
store.dispatchOnMain(WelcomeAction.HandleDeepLink(intent))
store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Welcome))
store.dispatchOnMain(WelcomeAction.ProceedWithBiometrics)
store.dispatchOnMain(WelcomeAction.HandleIntentIfNeeded(intent))
} else {
store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Home))
intentHandler.handleWalletConnectLink(intent)
intentHandler.handleIntent(intent, hasSavedUserWallets = false)
}
store.dispatch(BackupAction.CheckForUnfinishedBackup)
}

View file

@ -3,18 +3,33 @@ package com.tangem.tap.common
import android.content.Intent
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.os.Build
import com.tangem.tap.common.extensions.removePrefixOrNull
import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.domain.walletconnect.WalletConnectManager
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
import com.tangem.tap.features.home.redux.HomeAction
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.features.welcome.redux.WelcomeAction
import com.tangem.tap.scope
import com.tangem.tap.store
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import timber.log.Timber
class IntentHandler {
private val nfcActions = arrayOf(
NfcAdapter.ACTION_NDEF_DISCOVERED,
NfcAdapter.ACTION_TECH_DISCOVERED,
NfcAdapter.ACTION_TAG_DISCOVERED,
)
fun handleIntent(intent: Intent?, hasSavedUserWallets: Boolean) {
handleBackgroundScan(intent, hasSavedUserWallets)
handleWalletConnectLink(intent)
handleSellCurrencyCallback(intent)
}
fun handleWalletConnectLink(intent: Intent?) {
val wcUri = when (intent?.scheme) {
WalletConnectManager.WC_SCHEME -> {
@ -32,19 +47,29 @@ class IntentHandler {
}
}
fun handleBackgroundScan(intent: Intent?) {
if (intent != null && (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action ||
NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action
)
) {
val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
if (tag != null) {
intent.action = null
store.dispatch(NavigationAction.NavigateTo(AppScreen.Home))
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
store.dispatch(HomeAction.ReadCard())
}
fun handleBackgroundScan(intent: Intent?, hasSavedUserWallets: Boolean): Boolean {
if (intent == null || intent.action !in nfcActions) return false
val tag: Tag? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
intent.getParcelableExtra(NfcAdapter.EXTRA_TAG, Tag::class.java)
} else {
@Suppress("DEPRECATION")
intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
}
if (tag == null) return false
intent.action = null
if (hasSavedUserWallets) {
// TODO: Remove delay after [REDACTED_JIRA]
scope.launch {
delay(timeMillis = 200)
store.dispatch(WelcomeAction.ProceedWithCard)
}
} else {
store.dispatch(HomeAction.ReadCard())
}
return true
}
fun handleSellCurrencyCallback(intent: Intent?) {

View file

@ -15,7 +15,7 @@ internal sealed interface WelcomeAction : Action {
data class Error(val error: TangemError) : WelcomeAction
}
data class HandleDeepLink(val intent: Intent?) : WelcomeAction
data class HandleIntentIfNeeded(val intent: Intent?) : WelcomeAction
object CloseError : WelcomeAction
}

View file

@ -44,12 +44,14 @@ internal class WelcomeMiddleware {
is WelcomeAction.ProceedWithCard -> {
proceedWithCard(state)
}
is WelcomeAction.HandleIntentIfNeeded -> {
handleInitialIntent(action.intent)
}
is WelcomeAction.ProceedWithBiometrics.Error,
is WelcomeAction.ProceedWithCard.Error,
is WelcomeAction.ProceedWithBiometrics.Success,
is WelcomeAction.ProceedWithCard.Success,
is WelcomeAction.CloseError,
is WelcomeAction.HandleDeepLink,
-> Unit
}
}
@ -66,7 +68,7 @@ internal class WelcomeMiddleware {
store.dispatchOnMain(WelcomeAction.ProceedWithBiometrics.Success)
store.onUserWalletSelected(selectedUserWallet)
handleDeepLinkIfNeeded(state.deepLinkIntent)
intentHandler.handleWalletConnectLink(state.intent)
}
}
}
@ -85,13 +87,17 @@ internal class WelcomeMiddleware {
store.dispatchOnMain(WelcomeAction.ProceedWithCard.Success)
store.onUserWalletSelected(userWallet)
handleDeepLinkIfNeeded(state.deepLinkIntent)
intentHandler.handleWalletConnectLink(state.intent)
}
}
}
private fun handleDeepLinkIfNeeded(intent: Intent?) {
intentHandler.handleWalletConnectLink(intent)
private fun handleInitialIntent(intent: Intent?) {
val isBackgroundScanWasHandled = intentHandler.handleBackgroundScan(intent, hasSavedUserWallets = true)
if (!isBackgroundScanWasHandled) {
store.dispatchOnMain(WelcomeAction.ProceedWithBiometrics)
}
}
private suspend inline fun scanCardInternal(

View file

@ -12,7 +12,7 @@ internal object WelcomeReducer {
private fun internalReduce(action: WelcomeAction, state: WelcomeState): WelcomeState {
return when (action) {
is WelcomeAction.HandleDeepLink -> state.copy(deepLinkIntent = action.intent)
is WelcomeAction.HandleIntentIfNeeded -> state.copy(intent = action.intent)
is WelcomeAction.ProceedWithBiometrics -> state.copy(isUnlockWithBiometricsInProgress = true)
is WelcomeAction.ProceedWithCard -> state.copy(isUnlockWithCardInProgress = true)
is WelcomeAction.ProceedWithBiometrics.Error -> state.copy(

View file

@ -7,6 +7,6 @@ import org.rekotlin.StateType
data class WelcomeState(
val isUnlockWithBiometricsInProgress: Boolean = false,
val isUnlockWithCardInProgress: Boolean = false,
val deepLinkIntent: Intent? = null,
val intent: Intent? = null,
val error: TangemError? = null,
) : StateType