Updated on 2026-08-14
This commit is contained in:
commit
d314c8733a
21 changed files with 57 additions and 40 deletions
|
|
@ -108,11 +108,11 @@ internal var lockUserWalletsTimer: LockUserWalletsTimer? = null
|
||||||
var notificationsHandler: NotificationsHandler? = null
|
var notificationsHandler: NotificationsHandler? = null
|
||||||
|
|
||||||
private val coroutineContext: CoroutineContext
|
private val coroutineContext: CoroutineContext
|
||||||
get() = Job() + Dispatchers.IO + FeatureCoroutineExceptionHandler.create("scope")
|
get() = SupervisorJob() + Dispatchers.IO + FeatureCoroutineExceptionHandler.create("scope")
|
||||||
val scope = CoroutineScope(coroutineContext)
|
val scope = CoroutineScope(coroutineContext)
|
||||||
|
|
||||||
private val mainCoroutineContext: CoroutineContext
|
private val mainCoroutineContext: CoroutineContext
|
||||||
get() = Job() + Dispatchers.Main + FeatureCoroutineExceptionHandler.create("mainScope")
|
get() = SupervisorJob() + Dispatchers.Main + FeatureCoroutineExceptionHandler.create("mainScope")
|
||||||
val mainScope = CoroutineScope(mainCoroutineContext)
|
val mainScope = CoroutineScope(mainCoroutineContext)
|
||||||
|
|
||||||
@Suppress("LargeClass")
|
@Suppress("LargeClass")
|
||||||
|
|
|
||||||
|
|
@ -623,7 +623,12 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
|
||||||
if (action.unfinishedBackupScanResponse != null) {
|
if (action.unfinishedBackupScanResponse != null) {
|
||||||
// onboarding V2
|
// onboarding V2
|
||||||
store.dispatchNavigationAction {
|
store.dispatchNavigationAction {
|
||||||
push(AppRoute.Onboarding(scanResponse = action.unfinishedBackupScanResponse))
|
push(
|
||||||
|
AppRoute.Onboarding(
|
||||||
|
scanResponse = action.unfinishedBackupScanResponse,
|
||||||
|
mode = AppRoute.Onboarding.Mode.ContinueFinalize,
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import com.tangem.wallet.databinding.LayoutBackupAccessCodeBinding
|
||||||
|
|
||||||
class AccessCodeDialog(context: Context) : BottomSheetDialog(context) {
|
class AccessCodeDialog(context: Context) : BottomSheetDialog(context) {
|
||||||
|
|
||||||
var binding: LayoutBackupAccessCodeBinding? = null
|
private var binding: LayoutBackupAccessCodeBinding? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
@ -33,7 +33,7 @@ class AccessCodeDialog(context: Context) : BottomSheetDialog(context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showInfoScreen() = with(binding!!) {
|
fun showInfoScreen() = binding?.run {
|
||||||
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
behavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||||
accessCodeTitle.text = context.getText(R.string.onboarding_access_code_intro_title)
|
accessCodeTitle.text = context.getText(R.string.onboarding_access_code_intro_title)
|
||||||
layoutBackupAccessCodeInfo.root.show()
|
layoutBackupAccessCodeInfo.root.show()
|
||||||
|
|
@ -43,7 +43,7 @@ class AccessCodeDialog(context: Context) : BottomSheetDialog(context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showEnterAccessCode() = with(binding!!) {
|
fun showEnterAccessCode() = binding?.run {
|
||||||
layoutBackupAccessCodeInfo.root.hide()
|
layoutBackupAccessCodeInfo.root.hide()
|
||||||
layoutBackupAccessCodeSubmit.root.show()
|
layoutBackupAccessCodeSubmit.root.show()
|
||||||
accessCodeTitle.text = context.getText(R.string.onboarding_access_code_intro_title)
|
accessCodeTitle.text = context.getText(R.string.onboarding_access_code_intro_title)
|
||||||
|
|
@ -56,7 +56,7 @@ class AccessCodeDialog(context: Context) : BottomSheetDialog(context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showReenterAccessCode() = with(binding!!) {
|
fun showReenterAccessCode() = binding?.run {
|
||||||
layoutBackupAccessCodeInfo.root.hide()
|
layoutBackupAccessCodeInfo.root.hide()
|
||||||
layoutBackupAccessCodeSubmit.root.show()
|
layoutBackupAccessCodeSubmit.root.show()
|
||||||
accessCodeTitle.text = context.getText(R.string.onboarding_access_code_repeat_code_title)
|
accessCodeTitle.text = context.getText(R.string.onboarding_access_code_repeat_code_title)
|
||||||
|
|
@ -69,7 +69,7 @@ class AccessCodeDialog(context: Context) : BottomSheetDialog(context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showError(error: AccessCodeError?) = with(binding!!.layoutBackupAccessCodeSubmit) {
|
fun showError(error: AccessCodeError?) = binding?.layoutBackupAccessCodeSubmit?.run {
|
||||||
when (error) {
|
when (error) {
|
||||||
AccessCodeError.CodeTooShort ->
|
AccessCodeError.CodeTooShort ->
|
||||||
tilAccessCode.error = context.getString(R.string.onboarding_access_code_too_short)
|
tilAccessCode.error = context.getString(R.string.onboarding_access_code_too_short)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.tangem.tap.features.welcome.model
|
||||||
|
|
||||||
import com.tangem.common.core.TangemError
|
import com.tangem.common.core.TangemError
|
||||||
import com.tangem.core.analytics.Analytics
|
import com.tangem.core.analytics.Analytics
|
||||||
|
import com.tangem.core.decompose.di.ModelScoped
|
||||||
import com.tangem.core.decompose.model.Model
|
import com.tangem.core.decompose.model.Model
|
||||||
import com.tangem.core.decompose.model.ParamsContainer
|
import com.tangem.core.decompose.model.ParamsContainer
|
||||||
import com.tangem.core.navigation.finisher.AppFinisher
|
import com.tangem.core.navigation.finisher.AppFinisher
|
||||||
|
|
@ -14,7 +15,6 @@ import com.tangem.tap.features.welcome.redux.WelcomeAction
|
||||||
import com.tangem.tap.features.welcome.redux.WelcomeState
|
import com.tangem.tap.features.welcome.redux.WelcomeState
|
||||||
import com.tangem.tap.features.welcome.ui.WelcomeScreenState
|
import com.tangem.tap.features.welcome.ui.WelcomeScreenState
|
||||||
import com.tangem.tap.features.welcome.ui.model.WarningModel
|
import com.tangem.tap.features.welcome.ui.model.WarningModel
|
||||||
import com.tangem.tap.mainScope
|
|
||||||
import com.tangem.tap.store
|
import com.tangem.tap.store
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
@ -23,6 +23,7 @@ import org.rekotlin.StoreSubscriber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
// FIXME: Remove redux: [REDACTED_JIRA]
|
// FIXME: Remove redux: [REDACTED_JIRA]
|
||||||
|
@ModelScoped
|
||||||
internal class WelcomeModel @Inject constructor(
|
internal class WelcomeModel @Inject constructor(
|
||||||
override val dispatchers: CoroutineDispatcherProvider,
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val appFinisher: AppFinisher,
|
private val appFinisher: AppFinisher,
|
||||||
|
|
@ -40,8 +41,6 @@ internal class WelcomeModel @Inject constructor(
|
||||||
val state: MutableStateFlow<WelcomeScreenState> = MutableStateFlow(initialState)
|
val state: MutableStateFlow<WelcomeScreenState> = MutableStateFlow(initialState)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
store.dispatch(WelcomeAction.SetCoroutineScope(mainScope))
|
|
||||||
|
|
||||||
subscribeToStoreChanges()
|
subscribeToStoreChanges()
|
||||||
initGlobalState()
|
initGlobalState()
|
||||||
|
|
||||||
|
|
@ -87,7 +86,6 @@ internal class WelcomeModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
store.dispatch(WelcomeAction.ClearCoroutineScope)
|
|
||||||
store.unsubscribe(subscriber = this)
|
store.unsubscribe(subscriber = this)
|
||||||
|
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,10 @@ package com.tangem.tap.features.welcome.redux
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import com.tangem.common.core.TangemError
|
import com.tangem.common.core.TangemError
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import org.rekotlin.Action
|
import org.rekotlin.Action
|
||||||
|
|
||||||
internal sealed interface WelcomeAction : Action {
|
internal sealed interface WelcomeAction : Action {
|
||||||
|
|
||||||
data class SetCoroutineScope(val scope: CoroutineScope) : WelcomeAction
|
|
||||||
|
|
||||||
object ClearCoroutineScope : WelcomeAction
|
|
||||||
|
|
||||||
data class ProceedWithBiometrics(val afterUnlockIntent: Intent? = null) : WelcomeAction {
|
data class ProceedWithBiometrics(val afterUnlockIntent: Intent? = null) : WelcomeAction {
|
||||||
object Success : WelcomeAction
|
object Success : WelcomeAction
|
||||||
data class Error(val error: TangemError) : WelcomeAction
|
data class Error(val error: TangemError) : WelcomeAction
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import com.tangem.tap.common.extensions.*
|
||||||
import com.tangem.tap.common.redux.AppState
|
import com.tangem.tap.common.redux.AppState
|
||||||
import com.tangem.tap.features.intentHandler.handlers.BackgroundScanIntentHandler
|
import com.tangem.tap.features.intentHandler.handlers.BackgroundScanIntentHandler
|
||||||
import com.tangem.tap.features.intentHandler.handlers.WalletConnectLinkIntentHandler
|
import com.tangem.tap.features.intentHandler.handlers.WalletConnectLinkIntentHandler
|
||||||
|
import com.tangem.tap.mainScope
|
||||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||||
import com.tangem.tap.scope
|
import com.tangem.tap.scope
|
||||||
import com.tangem.tap.store
|
import com.tangem.tap.store
|
||||||
|
|
@ -44,7 +45,7 @@ internal class WelcomeMiddleware {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleAction(action: WelcomeAction, state: WelcomeState) {
|
private fun handleAction(action: WelcomeAction, state: WelcomeState) {
|
||||||
state.scope?.launch {
|
mainScope.launch {
|
||||||
when (action) {
|
when (action) {
|
||||||
is WelcomeAction.ProceedWithIntent -> proceedWithIntent(action.intent, scope = this)
|
is WelcomeAction.ProceedWithIntent -> proceedWithIntent(action.intent, scope = this)
|
||||||
is WelcomeAction.ProceedWithBiometrics -> proceedWithBiometrics(
|
is WelcomeAction.ProceedWithBiometrics -> proceedWithBiometrics(
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ internal object WelcomeReducer {
|
||||||
|
|
||||||
private fun internalReduce(action: WelcomeAction, state: WelcomeState): WelcomeState {
|
private fun internalReduce(action: WelcomeAction, state: WelcomeState): WelcomeState {
|
||||||
return when (action) {
|
return when (action) {
|
||||||
is WelcomeAction.SetCoroutineScope -> state.copy(scope = action.scope)
|
|
||||||
is WelcomeAction.ClearCoroutineScope -> state.copy(scope = null)
|
|
||||||
is WelcomeAction.ProceedWithIntent -> state.copy(intent = action.intent)
|
is WelcomeAction.ProceedWithIntent -> state.copy(intent = action.intent)
|
||||||
is WelcomeAction.ProceedWithBiometrics -> state.copy(isUnlockWithBiometricsInProgress = true)
|
is WelcomeAction.ProceedWithBiometrics -> state.copy(isUnlockWithBiometricsInProgress = true)
|
||||||
is WelcomeAction.ProceedWithCard -> state.copy(isUnlockWithCardInProgress = true)
|
is WelcomeAction.ProceedWithCard -> state.copy(isUnlockWithCardInProgress = true)
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,9 @@ package com.tangem.tap.features.welcome.redux
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import com.tangem.common.core.TangemError
|
import com.tangem.common.core.TangemError
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import org.rekotlin.StateType
|
import org.rekotlin.StateType
|
||||||
|
|
||||||
data class WelcomeState(
|
data class WelcomeState(
|
||||||
val scope: CoroutineScope? = null,
|
|
||||||
val isUnlockWithBiometricsInProgress: Boolean = false,
|
val isUnlockWithBiometricsInProgress: Boolean = false,
|
||||||
val isUnlockWithCardInProgress: Boolean = false,
|
val isUnlockWithCardInProgress: Boolean = false,
|
||||||
val intent: Intent? = null,
|
val intent: Intent? = null,
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,8 @@ internal class ChildFactory @Inject constructor(
|
||||||
AppRoute.Onboarding.Mode.WelcomeOnlyTwin -> OnboardingEntryComponent.Mode.WelcomeOnlyTwin
|
AppRoute.Onboarding.Mode.WelcomeOnlyTwin -> OnboardingEntryComponent.Mode.WelcomeOnlyTwin
|
||||||
AppRoute.Onboarding.Mode.RecreateWalletTwin ->
|
AppRoute.Onboarding.Mode.RecreateWalletTwin ->
|
||||||
OnboardingEntryComponent.Mode.RecreateWalletTwin
|
OnboardingEntryComponent.Mode.RecreateWalletTwin
|
||||||
|
AppRoute.Onboarding.Mode.ContinueFinalize ->
|
||||||
|
OnboardingEntryComponent.Mode.ContinueFinalize
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
componentFactory = onboardingEntryComponentFactory,
|
componentFactory = onboardingEntryComponentFactory,
|
||||||
|
|
@ -729,6 +731,8 @@ internal class ChildFactory @Inject constructor(
|
||||||
AppRoute.Onboarding.Mode.WelcomeOnlyTwin -> OnboardingEntryComponent.Mode.WelcomeOnlyTwin
|
AppRoute.Onboarding.Mode.WelcomeOnlyTwin -> OnboardingEntryComponent.Mode.WelcomeOnlyTwin
|
||||||
AppRoute.Onboarding.Mode.RecreateWalletTwin ->
|
AppRoute.Onboarding.Mode.RecreateWalletTwin ->
|
||||||
OnboardingEntryComponent.Mode.RecreateWalletTwin
|
OnboardingEntryComponent.Mode.RecreateWalletTwin
|
||||||
|
AppRoute.Onboarding.Mode.ContinueFinalize ->
|
||||||
|
OnboardingEntryComponent.Mode.ContinueFinalize
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
componentFactory = onboardingEntryComponentFactory,
|
componentFactory = onboardingEntryComponentFactory,
|
||||||
|
|
|
||||||
|
|
@ -268,6 +268,7 @@ sealed class AppRoute(val path: String) : Route {
|
||||||
AddBackupWallet1, // continue backup process for existing wallet 1
|
AddBackupWallet1, // continue backup process for existing wallet 1
|
||||||
WelcomeOnlyTwin, // show welcome screen and then navigate to wallet for twins
|
WelcomeOnlyTwin, // show welcome screen and then navigate to wallet for twins
|
||||||
RecreateWalletTwin, // reset twins
|
RecreateWalletTwin, // reset twins
|
||||||
|
ContinueFinalize, // continue finalize process (unfinished backup dialog)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,14 @@ import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@InstallIn(SingletonComponent::class)
|
@InstallIn(SingletonComponent::class)
|
||||||
internal object TxHistoryItemsStoreModule {
|
internal object TxHistoryItemsStoreModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
@Singleton
|
||||||
fun provideTxHistoryItemsStore(): TxHistoryItemsStore {
|
fun provideTxHistoryItemsStore(): TxHistoryItemsStore {
|
||||||
return DefaultTxHistoryItemsStore(
|
return DefaultTxHistoryItemsStore(
|
||||||
dataStore = RuntimeDataStore(),
|
dataStore = RuntimeDataStore(),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.tangem.core.ui.utils
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.MutableState
|
|
||||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||||
import com.google.accompanist.permissions.isGranted
|
import com.google.accompanist.permissions.isGranted
|
||||||
import com.google.accompanist.permissions.rememberPermissionState
|
import com.google.accompanist.permissions.rememberPermissionState
|
||||||
|
|
@ -16,7 +15,7 @@ import com.google.accompanist.permissions.rememberPermissionState
|
||||||
@Composable
|
@Composable
|
||||||
fun requestPushPermission(
|
fun requestPushPermission(
|
||||||
pushPermission: String?,
|
pushPermission: String?,
|
||||||
isClicked: MutableState<Boolean>,
|
isClicked: Boolean,
|
||||||
onAllow: () -> Unit,
|
onAllow: () -> Unit,
|
||||||
onDeny: () -> Unit,
|
onDeny: () -> Unit,
|
||||||
): () -> Unit {
|
): () -> Unit {
|
||||||
|
|
@ -26,7 +25,7 @@ fun requestPushPermission(
|
||||||
|
|
||||||
// Check if user granted permission and close bottom sheet
|
// Check if user granted permission and close bottom sheet
|
||||||
LaunchedEffect(key1 = permissionState?.status, isClicked) {
|
LaunchedEffect(key1 = permissionState?.status, isClicked) {
|
||||||
if (!isClicked.value) return@LaunchedEffect
|
if (!isClicked) return@LaunchedEffect
|
||||||
if (permissionState?.status?.isGranted == true) {
|
if (permissionState?.status?.isGranted == true) {
|
||||||
onAllow()
|
onAllow()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ interface OnboardingEntryComponent : ComposableContentComponent {
|
||||||
AddBackupWallet1,
|
AddBackupWallet1,
|
||||||
WelcomeOnlyTwin,
|
WelcomeOnlyTwin,
|
||||||
RecreateWalletTwin,
|
RecreateWalletTwin,
|
||||||
|
ContinueFinalize,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Factory : ComponentFactory<Params, OnboardingEntryComponent>
|
interface Factory : ComponentFactory<Params, OnboardingEntryComponent>
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ internal class OnboardingEntryModel @Inject constructor(
|
||||||
val multiWalletNavigationMode = when (params.mode) {
|
val multiWalletNavigationMode = when (params.mode) {
|
||||||
Mode.Onboarding -> OnboardingMultiWalletComponent.Mode.Onboarding
|
Mode.Onboarding -> OnboardingMultiWalletComponent.Mode.Onboarding
|
||||||
Mode.AddBackupWallet1 -> OnboardingMultiWalletComponent.Mode.AddBackup
|
Mode.AddBackupWallet1 -> OnboardingMultiWalletComponent.Mode.AddBackup
|
||||||
|
Mode.ContinueFinalize -> OnboardingMultiWalletComponent.Mode.ContinueFinalize
|
||||||
else -> error("Incorrect onboarding type")
|
else -> error("Incorrect onboarding type")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ interface OnboardingMultiWalletComponent : ComposableContentComponent, InnerNavi
|
||||||
enum class Mode {
|
enum class Mode {
|
||||||
Onboarding,
|
Onboarding,
|
||||||
AddBackup,
|
AddBackup,
|
||||||
|
ContinueFinalize,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Factory : ComponentFactory<Params, OnboardingMultiWalletComponent>
|
interface Factory : ComponentFactory<Params, OnboardingMultiWalletComponent>
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,8 @@ fun Wallet1ChooseOption(
|
||||||
Column(
|
Column(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.verticalScroll(rememberScrollState())
|
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.padding(top = 32.dp, bottom = 16.dp),
|
.padding(vertical = 16.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
) {
|
) {
|
||||||
val pagerState = rememberPagerState { CarouselItems.size }
|
val pagerState = rememberPagerState { CarouselItems.size }
|
||||||
|
|
@ -49,6 +48,8 @@ fun Wallet1ChooseOption(
|
||||||
HorizontalPager(pagerState) { selectedIndex ->
|
HorizontalPager(pagerState) { selectedIndex ->
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.verticalScroll(rememberScrollState())
|
||||||
.padding(start = 32.dp, end = 32.dp, bottom = 16.dp),
|
.padding(start = 32.dp, end = 32.dp, bottom = 16.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -226,7 +226,9 @@ internal class MultiWalletFinalizeModel @Inject constructor(
|
||||||
val userWalletCreated = createUserWallet(scanResponse)
|
val userWalletCreated = createUserWallet(scanResponse)
|
||||||
|
|
||||||
val userWallet = when (params.parentParams.mode) {
|
val userWallet = when (params.parentParams.mode) {
|
||||||
OnboardingMultiWalletComponent.Mode.Onboarding -> {
|
OnboardingMultiWalletComponent.Mode.Onboarding,
|
||||||
|
OnboardingMultiWalletComponent.Mode.ContinueFinalize,
|
||||||
|
-> {
|
||||||
userWalletsListManager.save(
|
userWalletsListManager.save(
|
||||||
userWallet = userWalletCreated.copy(
|
userWallet = userWalletCreated.copy(
|
||||||
scanResponse = scanResponse.updateScanResponseAfterBackup(),
|
scanResponse = scanResponse.updateScanResponseAfterBackup(),
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ internal class OnboardingMultiWalletModel @Inject constructor(
|
||||||
currentStep = getInitialStep(),
|
currentStep = getInitialStep(),
|
||||||
currentScanResponse = params.scanResponse,
|
currentScanResponse = params.scanResponse,
|
||||||
accessCode = null,
|
accessCode = null,
|
||||||
isThreeCards = true,
|
isThreeCards = isThreeCardsInit(),
|
||||||
resultUserWallet = null,
|
resultUserWallet = null,
|
||||||
startFromFinalize = getInitialStartFromFinalize(),
|
startFromFinalize = getInitialStartFromFinalize(),
|
||||||
),
|
),
|
||||||
|
|
@ -102,6 +102,8 @@ internal class OnboardingMultiWalletModel @Inject constructor(
|
||||||
val card = scanResponse.card
|
val card = scanResponse.card
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
|
params.mode == OnboardingMultiWalletComponent.Mode.ContinueFinalize ->
|
||||||
|
OnboardingMultiWalletState.Step.Finalize
|
||||||
// Add backup button
|
// Add backup button
|
||||||
// Wallet1 without backup and userwallet's scanResponse doesn't contain primary card.
|
// Wallet1 without backup and userwallet's scanResponse doesn't contain primary card.
|
||||||
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup &&
|
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup &&
|
||||||
|
|
@ -134,6 +136,18 @@ internal class OnboardingMultiWalletModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isThreeCardsInit(): Boolean {
|
||||||
|
val backupService = backupServiceHolder.backupService.get() ?: return true
|
||||||
|
return when (backupService.currentState) {
|
||||||
|
BackupService.State.FinalizingPrimaryCard,
|
||||||
|
is BackupService.State.FinalizingBackupCard,
|
||||||
|
-> {
|
||||||
|
backupService.addedBackupCardsCount > 1
|
||||||
|
}
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun initScreenTitle() {
|
private fun initScreenTitle() {
|
||||||
val title = screenTitleByStep(getInitialStep())
|
val title = screenTitleByStep(getInitialStep())
|
||||||
params.titleProvider.changeTitle(title)
|
params.titleProvider.changeTitle(title)
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import javax.inject.Inject
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
@ModelScoped
|
@ModelScoped
|
||||||
class PushNotificationsModel @Inject constructor(
|
internal class PushNotificationsModel @Inject constructor(
|
||||||
override val dispatchers: CoroutineDispatcherProvider,
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val neverRequestPermissionUseCase: NeverRequestPermissionUseCase,
|
private val neverRequestPermissionUseCase: NeverRequestPermissionUseCase,
|
||||||
private val neverToInitiallyAskPermissionUseCase: NeverToInitiallyAskPermissionUseCase,
|
private val neverToInitiallyAskPermissionUseCase: NeverToInitiallyAskPermissionUseCase,
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
package com.tangem.features.pushnotifications.impl.presentation.ui
|
package com.tangem.features.pushnotifications.impl.presentation.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.systemBarsPadding
|
import androidx.compose.foundation.layout.systemBarsPadding
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import com.tangem.core.ui.components.showcase.Showcase
|
import com.tangem.core.ui.components.showcase.Showcase
|
||||||
import com.tangem.core.ui.components.showcase.model.ShowcaseButtonModel
|
import com.tangem.core.ui.components.showcase.model.ShowcaseButtonModel
|
||||||
|
|
@ -21,7 +19,7 @@ internal fun PushNotificationsScreen(
|
||||||
onAllowPermission: () -> Unit,
|
onAllowPermission: () -> Unit,
|
||||||
onDenyPermission: () -> Unit,
|
onDenyPermission: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val isClicked = remember { mutableStateOf(false) }
|
var isClicked by remember { mutableStateOf(false) }
|
||||||
val requestPushPermission = requestPushPermission(
|
val requestPushPermission = requestPushPermission(
|
||||||
isClicked = isClicked,
|
isClicked = isClicked,
|
||||||
onAllow = onAllowPermission,
|
onAllow = onAllowPermission,
|
||||||
|
|
@ -45,7 +43,7 @@ internal fun PushNotificationsScreen(
|
||||||
primaryButton = ShowcaseButtonModel(
|
primaryButton = ShowcaseButtonModel(
|
||||||
buttonText = resourceReference(R.string.common_allow),
|
buttonText = resourceReference(R.string.common_allow),
|
||||||
onClick = {
|
onClick = {
|
||||||
isClicked.value = true
|
isClicked = true
|
||||||
onRequest()
|
onRequest()
|
||||||
requestPushPermission()
|
requestPushPermission()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,7 @@ import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import com.tangem.core.ui.components.PrimaryButton
|
import com.tangem.core.ui.components.PrimaryButton
|
||||||
|
|
@ -36,7 +34,7 @@ internal fun PushNotificationsBottomSheet(config: TangemBottomSheetConfig) {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun PushNotificationsSheetContent(content: PushNotificationsBottomSheetConfig, onDismiss: () -> Unit) {
|
private fun PushNotificationsSheetContent(content: PushNotificationsBottomSheetConfig, onDismiss: () -> Unit) {
|
||||||
val isClicked = remember { mutableStateOf(false) }
|
var isClicked by remember { mutableStateOf(false) }
|
||||||
val requestPushPermission = requestPushPermission(
|
val requestPushPermission = requestPushPermission(
|
||||||
pushPermission = getPushPermissionOrNull(),
|
pushPermission = getPushPermissionOrNull(),
|
||||||
isClicked = isClicked,
|
isClicked = isClicked,
|
||||||
|
|
@ -86,7 +84,7 @@ private fun PushNotificationsSheetContent(content: PushNotificationsBottomSheetC
|
||||||
PrimaryButton(
|
PrimaryButton(
|
||||||
text = stringResourceSafe(R.string.common_allow),
|
text = stringResourceSafe(R.string.common_allow),
|
||||||
onClick = {
|
onClick = {
|
||||||
isClicked.value = true
|
isClicked = true
|
||||||
content.onRequest()
|
content.onRequest()
|
||||||
requestPushPermission()
|
requestPushPermission()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue