Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-05 10:23:39 +03:00
parent aa6ddb9428
commit 9597f49fed
18 changed files with 556 additions and 97 deletions

View file

@ -105,6 +105,14 @@ internal class DefaultOnboardingEntryComponent @AssistedInject constructor(
}.saveIn(innerNavigationLinkJobHolder)
}
}
componentScope.launch {
model.titleProvider.currentTitle.collect { title ->
stepperComponent.state.update {
it.copy(title = title)
}
}
}
}
@Composable

View file

@ -3,14 +3,24 @@ package com.tangem.features.onboarding.v2.multiwallet.impl
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.decompose.extensions.compose.jetpack.stack.Children
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.slide
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.router.stack.*
import com.arkivanov.decompose.value.Value
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.decompose.navigation.inner.InnerNavigation
import com.tangem.core.decompose.navigation.inner.InnerNavigationState
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildComponent
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.MultiWalletBackupComponent
import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.MultiWalletCreateWalletComponent
import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiWalletModel
import com.tangem.features.onboarding.v2.multiwallet.impl.ui.OnboardingMultiWallet
import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiWalletState
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@ -23,24 +33,74 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
private val model: OnboardingMultiWalletModel = getOrCreateModel(params)
private val stackNavigation = StackNavigation<OnboardingMultiWalletState.Step>()
override val innerNavigation: InnerNavigation = object : InnerNavigation {
override val state = MutableStateFlow(
Wallet12InnerNavigationState(1, 5), // TODO
Wallet12InnerNavigationState(1, 5),
)
override fun pop(onComplete: (Boolean) -> Unit) {
// TODO
// TODO add warning dialog
stackNavigation.pop(onComplete)
}
}
private val childStack: Value<ChildStack<OnboardingMultiWalletState.Step, MultiWalletChildComponent>> = childStack(
key = "innerStack",
source = stackNavigation,
serializer = null,
initialConfiguration = model.state.value.currentStep,
handleBackButton = true,
childFactory = { configuration, factoryContext -> createChild(configuration, childByContext(factoryContext)) },
)
private fun createChild(
step: OnboardingMultiWalletState.Step,
childContext: AppComponentContext,
): MultiWalletChildComponent {
return when (step) {
OnboardingMultiWalletState.Step.CreateWallet -> MultiWalletCreateWalletComponent(
context = childContext,
params = MultiWalletChildParams(
multiWalletState = model.state,
parentParams = params,
),
onDone = ::onStepDone,
)
OnboardingMultiWalletState.Step.AddBackupDevice -> MultiWalletBackupComponent(
context = childContext,
params = MultiWalletChildParams(
multiWalletState = model.state,
parentParams = params,
),
onDone = ::onStepDone,
)
OnboardingMultiWalletState.Step.FinishBackup -> TODO()
OnboardingMultiWalletState.Step.Done -> TODO()
}
}
private fun onStepDone() {
when (model.state.value.currentStep) {
OnboardingMultiWalletState.Step.CreateWallet ->
stackNavigation.push(OnboardingMultiWalletState.Step.AddBackupDevice)
OnboardingMultiWalletState.Step.AddBackupDevice -> TODO()
OnboardingMultiWalletState.Step.FinishBackup -> TODO()
OnboardingMultiWalletState.Step.Done -> TODO()
}
}
@Composable
override fun Content(modifier: Modifier) {
val uiState by model.uiState.collectAsStateWithLifecycle()
val stackState by childStack.subscribeAsState()
OnboardingMultiWallet(
modifier = modifier,
state = uiState,
)
Children(
stack = stackState,
animation = stackAnimation(slide()),
) {
it.instance.Content(Modifier)
}
}
@AssistedFactory

View file

@ -0,0 +1,5 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child
import com.tangem.core.ui.decompose.ComposableContentComponent
interface MultiWalletChildComponent : ComposableContentComponent

View file

@ -0,0 +1,10 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiWalletState
import kotlinx.coroutines.flow.MutableStateFlow
class MultiWalletChildParams(
val multiWalletState: MutableStateFlow<OnboardingMultiWalletState>,
val parentParams: OnboardingMultiWalletComponent.Params,
)

View file

@ -0,0 +1,40 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child.backup
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.onboarding.v2.impl.R
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildComponent
import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.model.MultiWalletBackupModel
import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.ui.MultiWalletBackup
@Suppress("UnusedPrivateMember")
class MultiWalletBackupComponent(
context: AppComponentContext,
params: MultiWalletChildParams,
onDone: () -> Unit,
) : AppComponentContext by context, MultiWalletChildComponent {
private val model: MultiWalletBackupModel = getOrCreateModel(params)
init {
params.parentParams.titleProvider.changeTitle(
text = resourceReference(R.string.onboarding_navbar_title_creating_backup),
)
}
@Composable
override fun Content(modifier: Modifier) {
val state by model.uiState.collectAsStateWithLifecycle()
MultiWalletBackup(
modifier = modifier,
state = state,
)
}
}

View file

@ -0,0 +1,31 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.model
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.ui.state.MultiWalletBackupUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject
@ComponentScoped
class MultiWalletBackupModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
) : Model() {
@Suppress("UnusedPrivateMember")
private val params = paramsContainer.require<MultiWalletChildParams>()
private val _uiState = MutableStateFlow(
MultiWalletBackupUM(
finalizeButtonEnabled = false,
onAddBackupClick = {},
onFinalizeButtonClick = {},
),
)
val uiState: StateFlow<MultiWalletBackupUM> = _uiState
}

View file

@ -0,0 +1,73 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.PrimaryButtonIconEnd
import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.onboarding.v2.impl.R
import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.ui.state.MultiWalletBackupUM
@Composable
fun MultiWalletBackup(state: MultiWalletBackupUM, modifier: Modifier = Modifier) {
Column(
modifier = modifier
.fillMaxSize()
.navigationBarsPadding()
.verticalScroll(rememberScrollState()),
) {
Box(
Modifier
.fillMaxWidth()
.weight(1f),
) {
Box(
Modifier
.align(Alignment.Center)
.size(100.dp)
.background(Color.Black),
)
}
PrimaryButtonIconEnd(
modifier = Modifier
.padding(start = 16.dp, end = 16.dp, bottom = 12.dp)
.fillMaxWidth(),
iconResId = R.drawable.ic_tangem_24,
text = stringResource(R.string.onboarding_button_add_backup_card),
onClick = state.onAddBackupClick,
)
SecondaryButton(
modifier = Modifier
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
.fillMaxWidth(),
enabled = state.finalizeButtonEnabled,
text = stringResource(R.string.onboarding_button_finalize_backup),
onClick = state.onFinalizeButtonClick,
)
}
}
@Preview
@Composable
private fun Preview() {
TangemThemePreview {
MultiWalletBackup(
state = MultiWalletBackupUM(
finalizeButtonEnabled = true,
onAddBackupClick = {},
onFinalizeButtonClick = {},
),
)
}
}

View file

@ -0,0 +1,7 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.ui.state
data class MultiWalletBackupUM(
val finalizeButtonEnabled: Boolean,
val onAddBackupClick: () -> Unit,
val onFinalizeButtonClick: () -> Unit,
)

View file

@ -0,0 +1,44 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.onboarding.v2.impl.R
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildComponent
import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.model.MultiWalletCreateWalletModel
import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.ui.MultiWalletCreateWallet
import kotlinx.coroutines.launch
class MultiWalletCreateWalletComponent(
context: AppComponentContext,
params: MultiWalletChildParams,
onDone: () -> Unit,
) : AppComponentContext by context, MultiWalletChildComponent {
private val model: MultiWalletCreateWalletModel = getOrCreateModel(params)
init {
params.parentParams.titleProvider.changeTitle(
text = resourceReference(R.string.onboarding_create_wallet_header),
)
componentScope.launch {
model.onDone.collect { onDone() }
}
}
@Composable
override fun Content(modifier: Modifier) {
val state by model.uiState.collectAsStateWithLifecycle()
MultiWalletCreateWallet(
modifier = modifier,
state = state,
)
}
}

View file

@ -0,0 +1,16 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.model
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.onboarding.v2.impl.R
import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.ui.state.MultiWalletCreateWalletUM
internal fun resetCardDialog(onConfirm: () -> Unit, onDismiss: () -> Unit, onDismissButtonClick: () -> Unit) =
MultiWalletCreateWalletUM.Dialog(
title = resourceReference(R.string.onboarding_activation_error_title),
description = resourceReference(R.string.onboarding_activation_error_message),
confirmButtonText = resourceReference(R.string.common_ok),
dismissButtonText = resourceReference(R.string.common_support),
onDismiss = onDismiss,
onConfirm = onConfirm,
onDismissButtonClick = onDismissButtonClick,
)

View file

@ -0,0 +1,108 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.model
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.feedback.GetCardInfoUseCase
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.ui.state.MultiWalletCreateWalletUM
import com.tangem.sdk.api.TangemSdkManager
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject
@ComponentScoped
class MultiWalletCreateWalletModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
private val tangemSdkManager: TangemSdkManager,
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
private val getCardInfoUseCase: GetCardInfoUseCase,
) : Model() {
private val params = paramsContainer.require<MultiWalletChildParams>()
private val multiWalletState
get() = params.multiWalletState
private val _uiState = MutableStateFlow(
MultiWalletCreateWalletUM(
onCreateWalletClick = { createWallet(false) },
showSeedPhraseOption = params.parentParams.withSeedPhraseFlow,
onOtherOptionsClick = { /* navigate */ },
dialog = null,
),
)
val uiState: StateFlow<MultiWalletCreateWalletUM> = _uiState
val onDone = MutableSharedFlow<Unit>()
private fun createWallet(shouldReset: Boolean) {
modelScope.launch {
val result = tangemSdkManager.createProductWallet(
scanResponse = multiWalletState.value.currentScanResponse,
shouldReset = shouldReset,
)
when (result) {
is CompletionResult.Success -> {
multiWalletState.update {
it.copy(
currentScanResponse = it.currentScanResponse.copy(
card = result.data.card,
derivedKeys = result.data.derivedKeys,
primaryCard = result.data.primaryCard,
),
)
}
onDone.emit(Unit)
// TODO
// Analytics.send(Onboarding.CreateWallet.WalletCreatedSuccessfully())
}
is CompletionResult.Failure -> {
if (result.error is TangemSdkError.WalletAlreadyCreated) {
// show should reset dialog
handleActivationError()
}
}
}
}
}
private fun handleActivationError() {
_uiState.update { state ->
state.copy(
dialog = resetCardDialog(
onConfirm = {
_uiState.update { it.copy(dialog = null) }
resetCard()
},
onDismiss = {
_uiState.update { it.copy(dialog = null) }
},
onDismissButtonClick = ::navigateToSupportScreen,
),
)
}
}
private fun resetCard() {
createWallet(true)
}
fun navigateToSupportScreen() {
modelScope.launch {
val cardInfo = getCardInfoUseCase(multiWalletState.value.currentScanResponse).getOrNull() ?: return@launch
sendFeedbackEmailUseCase(FeedbackEmailType.DirectUserRequest(cardInfo))
}
}
}

View file

@ -0,0 +1,92 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.BasicDialog
import com.tangem.core.ui.components.DialogButtonUM
import com.tangem.core.ui.components.PrimaryButtonIconEnd
import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.onboarding.v2.impl.R
import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.ui.state.MultiWalletCreateWalletUM
@Composable
fun MultiWalletCreateWallet(state: MultiWalletCreateWalletUM, modifier: Modifier = Modifier) {
if (state.dialog != null) {
BasicDialog(
title = state.dialog.title.resolveReference(),
message = state.dialog.description.resolveReference(),
confirmButton = DialogButtonUM(
title = state.dialog.confirmButtonText.resolveReference(),
onClick = state.dialog.onConfirm,
),
dismissButton = DialogButtonUM(
title = state.dialog.dismissButtonText.resolveReference(),
onClick = state.dialog.onDismissButtonClick,
),
onDismissDialog = state.dialog.onDismiss,
)
}
Column(
modifier = modifier
.fillMaxSize()
.navigationBarsPadding()
.verticalScroll(rememberScrollState()),
) {
Box(
Modifier
.fillMaxWidth()
.weight(1f),
) {
Box(
Modifier
.align(Alignment.Center)
.size(100.dp)
.background(Color.Black),
)
}
PrimaryButtonIconEnd(
modifier = Modifier
.padding(start = 16.dp, end = 16.dp, bottom = 12.dp)
.fillMaxWidth(),
iconResId = R.drawable.ic_tangem_24,
text = stringResource(R.string.onboarding_create_wallet_button_create_wallet),
onClick = state.onCreateWalletClick,
)
SecondaryButton(
modifier = Modifier
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
.fillMaxWidth(),
text = stringResource(R.string.onboarding_create_wallet_options_button_options),
onClick = state.onOtherOptionsClick,
)
}
}
@Preview
@Composable
private fun Preview() {
TangemThemePreview {
MultiWalletCreateWallet(
state = MultiWalletCreateWalletUM(
onCreateWalletClick = {},
showSeedPhraseOption = true,
onOtherOptionsClick = {},
dialog = null,
),
)
}
}

View file

@ -0,0 +1,20 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.ui.state
import com.tangem.core.ui.extensions.TextReference
data class MultiWalletCreateWalletUM(
val onCreateWalletClick: () -> Unit,
val showSeedPhraseOption: Boolean,
val onOtherOptionsClick: () -> Unit,
val dialog: Dialog?,
) {
data class Dialog(
val title: TextReference,
val description: TextReference,
val dismissButtonText: TextReference,
val confirmButtonText: TextReference,
val onConfirm: () -> Unit,
val onDismissButtonClick: () -> Unit,
val onDismiss: () -> Unit,
)
}

View file

@ -4,6 +4,8 @@ import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
import com.tangem.features.onboarding.v2.multiwallet.impl.DefaultOnboardingMultiWalletComponent
import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.model.MultiWalletBackupModel
import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.model.MultiWalletCreateWalletModel
import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiWalletModel
import dagger.Binds
import dagger.Module
@ -30,4 +32,14 @@ internal interface ModelModule {
@IntoMap
@ClassKey(OnboardingMultiWalletModel::class)
fun provideModel(model: OnboardingMultiWalletModel): Model
@Binds
@IntoMap
@ClassKey(MultiWalletBackupModel::class)
fun provideModel2(model: MultiWalletBackupModel): Model
@Binds
@IntoMap
@ClassKey(MultiWalletCreateWalletModel::class)
fun provideModel3(model: MultiWalletCreateWalletModel): Model
}

View file

@ -1,22 +1,14 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.model
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.feedback.GetCardInfoUseCase
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.models.scan.CardDTO
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
import com.tangem.features.onboarding.v2.multiwallet.impl.ui.state.OnboardingMultiWalletUM
import com.tangem.sdk.api.TangemSdkManager
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject
@ -24,27 +16,14 @@ import javax.inject.Inject
internal class OnboardingMultiWalletModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
private val tangemSdkManager: TangemSdkManager,
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
private val getCardInfoUseCase: GetCardInfoUseCase,
) : Model() {
private val params = paramsContainer.require<OnboardingMultiWalletComponent.Params>()
private val currentScanResponse = MutableStateFlow(params.scanResponse)
val state = MutableStateFlow(
OnboardingMultiWalletState(
currentStep = getInitialStep(),
),
)
val uiState = MutableStateFlow(
OnboardingMultiWalletUM(
onCreateWalletClick = { createWallet(false) },
showSeedPhraseOption = params.withSeedPhraseFlow,
onOtherOptionsClick = { /* navigate */ },
onBack = { },
dialog = null,
currentScanResponse = params.scanResponse,
),
)
@ -53,7 +32,7 @@ internal class OnboardingMultiWalletModel @Inject constructor(
}
private fun getInitialStep(): OnboardingMultiWalletState.Step {
val card = currentScanResponse.value.card
val card = params.scanResponse.card
return when {
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup ->
@ -78,63 +57,4 @@ internal class OnboardingMultiWalletModel @Inject constructor(
}
}
}
private fun createWallet(shouldReset: Boolean) {
modelScope.launch {
val result = tangemSdkManager.createProductWallet(
scanResponse = currentScanResponse.value,
shouldReset = shouldReset,
)
when (result) {
is CompletionResult.Success -> {
currentScanResponse.update {
it.copy(
card = result.data.card,
derivedKeys = result.data.derivedKeys,
primaryCard = result.data.primaryCard,
)
}
// TODO
// Analytics.send(Onboarding.CreateWallet.WalletCreatedSuccessfully())
}
is CompletionResult.Failure -> {
if (result.error is TangemSdkError.WalletAlreadyCreated) {
// show should reset dialog
handleActivationError()
}
}
}
}
}
private fun handleActivationError() {
uiState.update {
it.copy(
dialog = resetCardDialog(
onConfirm = {
uiState.update { it.copy(dialog = null) }
resetCard()
},
onDismiss = {
uiState.update { it.copy(dialog = null) }
},
onDismissButtonClick = ::navigateToSupportScreen,
),
)
}
}
private fun resetCard() {
createWallet(true)
}
fun navigateToSupportScreen() {
modelScope.launch {
val cardInfo = getCardInfoUseCase(currentScanResponse.value).getOrNull() ?: return@launch
sendFeedbackEmailUseCase(FeedbackEmailType.DirectUserRequest(cardInfo))
}
}
}

View file

@ -1,10 +1,13 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.model
import com.tangem.domain.models.scan.ScanResponse
data class OnboardingMultiWalletState(
val currentStep: Step,
val currentScanResponse: ScanResponse,
) {
enum class Step {
GeneratePrivateKeys, CreateWallet, AddBackupDevice, FinishBackup, Done
CreateWallet, AddBackupDevice, FinishBackup, Done
}
}

View file

@ -5,9 +5,10 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.onboarding.v2.impl.R
fun screenTitleByStep(step: OnboardingMultiWalletState.Step): TextReference = when (step) {
OnboardingMultiWalletState.Step.GeneratePrivateKeys -> TODO()
OnboardingMultiWalletState.Step.CreateWallet -> resourceReference(R.string.onboarding_create_wallet_header)
OnboardingMultiWalletState.Step.AddBackupDevice -> TODO()
OnboardingMultiWalletState.Step.CreateWallet ->
resourceReference(R.string.onboarding_create_wallet_header)
OnboardingMultiWalletState.Step.AddBackupDevice ->
resourceReference(R.string.onboarding_navbar_title_creating_backup)
OnboardingMultiWalletState.Step.FinishBackup -> TODO()
OnboardingMultiWalletState.Step.Done -> TODO()
}

View file

@ -17,6 +17,7 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import timber.log.Timber
internal class DefaultOnboardingStepperComponent @AssistedInject constructor(
@Assisted val context: AppComponentContext,
@ -27,6 +28,14 @@ internal class DefaultOnboardingStepperComponent @AssistedInject constructor(
override val state = instanceKeeper.getOrCreateSimple { MutableStateFlow(params.initState) }
init {
componentScope.launch {
state.collect {
Timber.tag("ASDASD").d("State: $it")
}
}
}
private fun openSupport() {
componentScope.launch {
val cardInfo = getCardInfoUseCase(params.scanResponse).getOrNull() ?: return@launch
@ -36,10 +45,10 @@ internal class DefaultOnboardingStepperComponent @AssistedInject constructor(
@Composable
override fun Content(modifier: Modifier) {
val state by state.collectAsStateWithLifecycle()
val uiState by state.collectAsStateWithLifecycle()
OnboardingStepper(
state = state,
state = uiState,
onBackClick = remember(this) { params.popBack },
onSupportButtonClick = remember(this) { ::openSupport },
modifier = modifier,