diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 429cbe3e57..17b20dbe41 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -8,6 +8,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsControllerCompat +import androidx.lifecycle.lifecycleScope import by.kirich1409.viewbindingdelegate.viewBinding import com.google.android.material.snackbar.Snackbar import com.tangem.core.navigation.AppScreen @@ -180,7 +181,12 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac private fun initIntentHandlers() { val hasSavedWalletsProvider = { store.state.globalState.userWalletsListManager?.hasUserWallets == true } - intentProcessor.addHandler(BackgroundScanIntentHandler(hasSavedWalletsProvider)) + intentProcessor.addHandler( + BackgroundScanIntentHandler( + hasSavedWalletsProvider, + lifecycleScope, + ), + ) intentProcessor.addHandler(WalletConnectLinkIntentHandler()) intentProcessor.addHandler(BuyCurrencyIntentHandler()) intentProcessor.addHandler(SellCurrencyIntentHandler()) @@ -222,7 +228,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac */ cardSdkLifecycleObserver.onCreate(context = this) - scope.launch { + lifecycleScope.launch { intentProcessor.handleIntent(intent) } } @@ -294,8 +300,11 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac if (store.state.globalState.userWalletsListManager?.hasUserWallets == true) { store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Welcome)) store.dispatchOnMain(WelcomeAction.SetInitialIntent(intentWhichStartedActivity)) - scope.launch { - val handler = BackgroundScanIntentHandler(hasSavedUserWalletsProvider = { true }) + lifecycleScope.launch { + val handler = BackgroundScanIntentHandler( + hasSavedUserWalletsProvider = { true }, + lifecycleCoroutineScope = lifecycleScope, + ) val isBackgroundScanHandled = handler.handleIntent(intentWhichStartedActivity) val hasNotIncompletedBackup = !backupService.hasIncompletedBackup if (!isBackgroundScanHandled && hasNotIncompletedBackup) { @@ -304,7 +313,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac } } else { store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Home)) - scope.launch { + lifecycleScope.launch { intentProcessor.handleIntent(intentWhichStartedActivity) } } diff --git a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt index 95b558c438..1f6f2abc69 100644 --- a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt @@ -13,6 +13,7 @@ import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsControllerCompat import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.lifecycle.lifecycleScope import com.tangem.core.analytics.Analytics import com.tangem.core.navigation.AppScreen import com.tangem.core.navigation.NavigationAction @@ -26,6 +27,7 @@ import com.tangem.tap.features.home.redux.Stories import com.tangem.tap.features.tokens.legacy.redux.TokensAction import com.tangem.tap.store import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch import org.rekotlin.StoreSubscriber @AndroidEntryPoint @@ -94,7 +96,11 @@ class HomeFragment : Fragment(), StoreSubscriber { onLearn2earnClick = learn2earnViewModel.uiState.storyScreenState.onClick, onScanButtonClick = { Analytics.send(IntroductionProcess.ButtonScanCard()) - store.dispatch(HomeAction.ReadCard()) + lifecycleScope.launch { + store.dispatch( + HomeAction.ReadCard(lifecycleCoroutineScope = lifecycleScope), + ) + } }, onShopButtonClick = { Analytics.send(IntroductionProcess.ButtonBuyCards()) diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt index 93479d1767..18fbd8f4fb 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt @@ -1,5 +1,6 @@ package com.tangem.tap.features.home.redux +import androidx.lifecycle.LifecycleCoroutineScope import com.tangem.core.analytics.models.AnalyticsEvent import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Basic @@ -13,8 +14,16 @@ sealed class HomeAction : Action { data class InsertStory(val position: Int, val story: Stories) : HomeAction() + /** + * Action for scanning card + * + * @property analyticsEvent analytics event + * @property lifecycleCoroutineScope lifecycle scope. It will be canceled when lifecycle-aware component is + * destroyed. + */ data class ReadCard( val analyticsEvent: AnalyticsEvent? = Basic.CardWasScanned(AnalyticsParam.ScannedFrom.Introduction), + val lifecycleCoroutineScope: LifecycleCoroutineScope, ) : HomeAction() data class ScanInProgress(val scanInProgress: Boolean) : HomeAction() diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt index 162d99281a..48f2f37be5 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt @@ -1,5 +1,6 @@ package com.tangem.tap.features.home.redux +import androidx.lifecycle.LifecycleCoroutineScope import com.tangem.common.doOnFailure import com.tangem.common.doOnResult import com.tangem.common.doOnSuccess @@ -62,7 +63,7 @@ private fun handleHomeAction(action: Action) { store.dispatch(GlobalAction.FetchUserCountry) } is HomeAction.ReadCard -> { - readCard(action.analyticsEvent) + readCard(action.analyticsEvent, action.lifecycleCoroutineScope) } is HomeAction.GoToShop -> { Analytics.send(Shop.ScreenOpened()) @@ -77,32 +78,34 @@ private fun handleHomeAction(action: Action) { } } -private fun readCard(analyticsEvent: AnalyticsEvent?) = scope.launch { - delay(timeMillis = 200) - store.state.daggerGraphState.get(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy( - isBiometricsRequestPolicy = preferencesStorage.shouldSaveAccessCodes, - ) +private fun readCard(analyticsEvent: AnalyticsEvent?, lifecycleCoroutineScope: LifecycleCoroutineScope) { + lifecycleCoroutineScope.launch { + delay(timeMillis = 200) + store.state.daggerGraphState.get(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy( + isBiometricsRequestPolicy = preferencesStorage.shouldSaveAccessCodes, + ) - store.state.daggerGraphState.get(DaggerGraphState::scanCardProcessor).scan( - analyticsEvent = analyticsEvent, - onProgressStateChange = { showProgress -> - if (showProgress) { - changeButtonState(ButtonState.PROGRESS) - } else { + store.state.daggerGraphState.get(DaggerGraphState::scanCardProcessor).scan( + analyticsEvent = analyticsEvent, + onProgressStateChange = { showProgress -> + if (showProgress) { + changeButtonState(ButtonState.PROGRESS) + } else { + changeButtonState(ButtonState.ENABLED) + } + }, + onScanStateChange = { scanInProgress -> + store.dispatch(HomeAction.ScanInProgress(scanInProgress)) + }, + onFailure = { + Timber.e(it, "Unable to scan card") changeButtonState(ButtonState.ENABLED) - } - }, - onScanStateChange = { scanInProgress -> - store.dispatch(HomeAction.ScanInProgress(scanInProgress)) - }, - onFailure = { - Timber.e(it, "Unable to scan card") - changeButtonState(ButtonState.ENABLED) - }, - onSuccess = { scanResponse -> - proceedWithScanResponse(scanResponse) - }, - ) + }, + onSuccess = { scanResponse -> + proceedWithScanResponse(scanResponse) + }, + ) + } } private fun proceedWithScanResponse(scanResponse: ScanResponse) = scope.launch { diff --git a/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BackgroundScanIntentHandler.kt b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BackgroundScanIntentHandler.kt index df5b3759d8..09a682cdb5 100644 --- a/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BackgroundScanIntentHandler.kt +++ b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BackgroundScanIntentHandler.kt @@ -4,11 +4,11 @@ import android.content.Intent import android.nfc.NfcAdapter import android.nfc.Tag import android.os.Build +import androidx.lifecycle.LifecycleCoroutineScope import com.tangem.tap.common.extensions.dispatchWithMain import com.tangem.tap.features.home.redux.HomeAction import com.tangem.tap.features.intentHandler.IntentHandler 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 @@ -18,6 +18,7 @@ import kotlinx.coroutines.launch */ class BackgroundScanIntentHandler( private val hasSavedUserWalletsProvider: () -> Boolean, + private val lifecycleCoroutineScope: LifecycleCoroutineScope, ) : IntentHandler { private val nfcActions = arrayOf( @@ -40,12 +41,12 @@ class BackgroundScanIntentHandler( intent.action = null if (hasSavedUserWalletsProvider.invoke()) { // TODO: Remove delay after [REDACTED_JIRA] - scope.launch { + lifecycleCoroutineScope.launch { delay(timeMillis = 200) - store.dispatchWithMain(WelcomeAction.ProceedWithCard) + store.dispatchWithMain(WelcomeAction.ProceedWithCard(lifecycleCoroutineScope)) } } else { - store.dispatchWithMain(HomeAction.ReadCard()) + store.dispatchWithMain(HomeAction.ReadCard(lifecycleCoroutineScope = lifecycleCoroutineScope)) } return true diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt index b1f339be2a..9446f718c1 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt @@ -1,6 +1,7 @@ package com.tangem.tap.features.onboarding.products.wallet.redux import android.net.Uri +import androidx.lifecycle.LifecycleCoroutineScope import com.tangem.common.CompletionResult import com.tangem.feature.onboarding.data.model.CreateWalletResponse import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSource @@ -17,7 +18,7 @@ sealed class OnboardingWalletAction : Action { ) : OnboardingWalletAction() object Done : OnboardingWalletAction() - object FinishOnboarding : OnboardingWalletAction() + data class FinishOnboarding(val lifecycleCoroutineScope: LifecycleCoroutineScope) : OnboardingWalletAction() object ResumeBackup : OnboardingWalletAction() diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt index 7d3b5e7eb1..b255ab3536 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt @@ -146,12 +146,12 @@ private fun handleWalletAction(action: Action) { is CompletionResult.Failure -> Unit } } - OnboardingWalletAction.FinishOnboarding -> { + is OnboardingWalletAction.FinishOnboarding -> { store.dispatch(GlobalAction.Onboarding.Stop) if (scanResponse == null) { store.dispatch(NavigationAction.PopBackTo()) - store.dispatch(HomeAction.ReadCard()) + store.dispatch(HomeAction.ReadCard(lifecycleCoroutineScope = action.lifecycleCoroutineScope)) } else { val backupState = store.state.onboardingWalletState.backupState val updatedScanResponse = updateScanResponseAfterBackup(scanResponse, backupState) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt index b1021876bc..ff40ab5ad6 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt @@ -11,6 +11,7 @@ import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import androidx.core.view.MenuProvider import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import androidx.transition.TransitionInflater import androidx.transition.TransitionManager import by.kirich1409.viewbindingdelegate.viewBinding @@ -428,7 +429,9 @@ class OnboardingWalletFragment : layoutButtonsCommon.btnWalletAlternativeAction.hide() layoutButtonsCommon.btnWalletMainAction.setOnClickListener { showConfetti(false) - store.dispatch(OnboardingWalletAction.FinishOnboarding) + lifecycleScope.launch { + store.dispatch(OnboardingWalletAction.FinishOnboarding(lifecycleCoroutineScope = lifecycleScope)) + } } animator.showSuccess { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt index 10803cf57f..adca4f96f4 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt @@ -1,6 +1,7 @@ package com.tangem.tap.features.wallet.redux import android.content.Context +import androidx.lifecycle.LifecycleCoroutineScope import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.address.AddressType import com.tangem.core.analytics.models.AnalyticsEvent @@ -73,7 +74,10 @@ sealed class WalletAction : Action { class CheckRemainingSignatures(val remainingSignatures: Int?) : Warnings() } - data class Scan(val onScanSuccessEvent: AnalyticsEvent?) : WalletAction() + data class Scan( + val onScanSuccessEvent: AnalyticsEvent?, + val lifecycleScope: LifecycleCoroutineScope, + ) : WalletAction() data class Send(val amount: Amount? = null) : WalletAction() @@ -109,7 +113,7 @@ sealed class WalletAction : Action { data class ExploreAddress(val exploreUrl: String, val context: Context) : WalletAction() object CreateWallet : WalletAction() - object ChangeWallet : WalletAction() + data class ChangeWallet(val lifecycleScope: LifecycleCoroutineScope) : WalletAction() object ShowSaveWalletIfNeeded : WalletAction() sealed class TradeCryptoAction : WalletAction() { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index c84ac7fa2d..2072690c1c 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -1,5 +1,6 @@ package com.tangem.tap.features.wallet.redux.middlewares +import androidx.lifecycle.LifecycleCoroutineScope import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.AmountType @@ -114,9 +115,9 @@ class WalletMiddleware { } is WalletAction.Scan -> { store.dispatch(NavigationAction.PopBackTo(AppScreen.Home)) - scope.launch { + action.lifecycleScope.launch { delay(timeMillis = 700) - store.dispatchOnMain(HomeAction.ReadCard(action.onScanSuccessEvent)) + store.dispatchOnMain(HomeAction.ReadCard(action.onScanSuccessEvent, action.lifecycleScope)) } } is WalletAction.LoadData, @@ -225,7 +226,7 @@ class WalletMiddleware { showSaveWalletIfNeeded() } is WalletAction.ChangeWallet -> { - changeWallet(walletState) + changeWallet(walletState, action.lifecycleScope) } is WalletAction.UserWalletChanged -> Unit is WalletAction.WalletStoresChanged -> { @@ -378,7 +379,7 @@ class WalletMiddleware { } } - private fun changeWallet(state: WalletState) { + private fun changeWallet(state: WalletState, lifecycleScope: LifecycleCoroutineScope) { when { state.canSaveUserWallets -> { Analytics.send(MainScreen.ButtonMyWallets()) @@ -386,7 +387,12 @@ class WalletMiddleware { } else -> { Analytics.send(MainScreen.ButtonScanCard()) - store.dispatch(WalletAction.Scan(Basic.CardWasScanned(AnalyticsParam.ScannedFrom.Main))) + store.dispatch( + WalletAction.Scan( + onScanSuccessEvent = Basic.CardWasScanned(AnalyticsParam.ScannedFrom.Main), + lifecycleScope = lifecycleScope, + ), + ) } } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index af1d2100aa..bcbad9fc7a 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -141,7 +141,11 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), SafeStoreSubscriber proceedWithBiometrics(state) - is WelcomeAction.ProceedWithCard -> proceedWithCard(state) + is WelcomeAction.ProceedWithCard -> proceedWithCard(state, action.lifecycleCoroutineScope) is WelcomeAction.ClearUserWallets -> disableUserWalletsSaving() else -> Unit } @@ -77,25 +78,27 @@ internal class WelcomeMiddleware { } } - private fun proceedWithCard(state: WelcomeState) = scope.launch { - scanCardInternal { scanResponse -> - val userWallet = UserWalletBuilder(scanResponse).build() ?: return@scanCardInternal + private fun proceedWithCard(state: WelcomeState, lifecycleCoroutineScope: LifecycleCoroutineScope) { + lifecycleCoroutineScope.launch { + scanCardInternal { scanResponse -> + val userWallet = UserWalletBuilder(scanResponse).build() ?: return@scanCardInternal - userWalletsListManager.save(userWallet, canOverride = true) - .doOnFailure { error -> - Timber.e(error, "Unable to save user wallet") - store.dispatchOnMain(WelcomeAction.ProceedWithCard.Error(error)) - } - .doOnSuccess { - store.dispatchOnMain(SignInAction.SetSignInType(Basic.SignedIn.SignInType.Card)) - store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Wallet)) - store.dispatchOnMain(WelcomeAction.ProceedWithCard.Success) - store.onUserWalletSelected(userWallet = userWallet) - - state.intent?.let { - WalletConnectLinkIntentHandler().handleIntent(it) + userWalletsListManager.save(userWallet, canOverride = true) + .doOnFailure { error -> + Timber.e(error, "Unable to save user wallet") + store.dispatchOnMain(WelcomeAction.ProceedWithCard.Error(error)) } - } + .doOnSuccess { + store.dispatchOnMain(SignInAction.SetSignInType(Basic.SignedIn.SignInType.Card)) + store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Wallet)) + store.dispatchOnMain(WelcomeAction.ProceedWithCard.Success) + store.onUserWalletSelected(userWallet = userWallet) + + state.intent?.let { + WalletConnectLinkIntentHandler().handleIntent(it) + } + } + } } } diff --git a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeFragment.kt b/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeFragment.kt index 0554bdf27c..0713e33482 100644 --- a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeFragment.kt @@ -7,17 +7,12 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.material.SnackbarHost import androidx.compose.material.SnackbarHostState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.State -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.colorResource import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import com.tangem.core.analytics.Analytics import com.tangem.core.ui.components.SystemBarsEffect import com.tangem.core.ui.fragments.ComposeFragment @@ -67,7 +62,7 @@ internal class WelcomeFragment : ComposeFragment() { showUnlockProgress = state.showUnlockWithBiometricsProgress, showScanCardProgress = state.showUnlockWithCardProgress, onUnlockClick = viewModel::unlockWallets, - onScanCardClick = viewModel::scanCard, + onScanCardClick = { viewModel.scanCard(lifecycleCoroutineScope = lifecycleScope) }, ) SnackbarHost( diff --git a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeViewModel.kt b/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeViewModel.kt index 3731da6378..4f7587289d 100644 --- a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeViewModel.kt @@ -1,5 +1,6 @@ package com.tangem.tap.features.welcome.ui +import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.ViewModel import com.tangem.common.core.TangemError import com.tangem.core.analytics.Analytics @@ -30,9 +31,9 @@ internal class WelcomeViewModel : ViewModel(), StoreSubscriber { store.dispatch(WelcomeAction.ProceedWithBiometrics) } - fun scanCard() { + fun scanCard(lifecycleCoroutineScope: LifecycleCoroutineScope) { Analytics.send(SignIn.ButtonCardSignIn()) - store.dispatch(WelcomeAction.ProceedWithCard) + store.dispatch(WelcomeAction.ProceedWithCard(lifecycleCoroutineScope)) } fun closeError() {