Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-27 20:47:11 +05:00
parent e51453c99b
commit 9ab23a953d
21 changed files with 343 additions and 233 deletions

View file

@ -0,0 +1,3 @@
package com.tangem.features.hotwallet.accesscode
const val ACCESS_CODE_LENGTH = 6

View file

@ -0,0 +1,52 @@
package com.tangem.features.hotwallet.accesscode.confirm
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.decompose.ComposableContentComponent
import com.tangem.core.ui.security.DisableScreenshotsDisposableEffect
import com.tangem.features.hotwallet.accesscode.confirm.ui.SetAccessCodeConfirmContent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
internal class ConfirmAccessCodeComponent @AssistedInject constructor(
@Assisted private val context: AppComponentContext,
@Assisted private val params: Params,
) : ComposableContentComponent, AppComponentContext by context {
private val model: ConfirmAccessCodeModel = getOrCreateModel(params)
@Composable
override fun Content(modifier: Modifier) {
val state by model.uiState.collectAsStateWithLifecycle()
DisableScreenshotsDisposableEffect()
SetAccessCodeConfirmContent(
accessCode = state.accessCode,
onAccessCodeChange = state.onAccessCodeChange,
accessCodeLength = state.accessCodeLength,
onConfirm = state.onConfirm,
buttonEnabled = state.buttonEnabled,
modifier = modifier,
)
}
interface ModelCallbacks {
fun onAccessCodeConfirmed()
}
data class Params(
val accessCodeToConfirm: String,
val callbacks: ModelCallbacks,
)
@AssistedFactory
interface Factory {
fun create(context: AppComponentContext, params: Params): ConfirmAccessCodeComponent
}
}

View file

@ -0,0 +1,45 @@
package com.tangem.features.hotwallet.accesscode.confirm
import androidx.compose.runtime.Stable
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.features.hotwallet.accesscode.confirm.entity.ConfirmAccessCodeUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import javax.inject.Inject
@Stable
@ModelScoped
internal class ConfirmAccessCodeModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
) : Model() {
private val params = paramsContainer.require<ConfirmAccessCodeComponent.Params>()
internal val uiState: StateFlow<ConfirmAccessCodeUM>
field = MutableStateFlow(getInitialState())
private fun getInitialState() = ConfirmAccessCodeUM(
accessCode = "",
onAccessCodeChange = ::onAccessCodeChange,
buttonEnabled = false,
onConfirm = ::onConfirm,
)
private fun onAccessCodeChange(value: String) {
uiState.update {
it.copy(
accessCode = value,
buttonEnabled = value == params.accessCodeToConfirm,
)
}
}
private fun onConfirm() {
params.callbacks.onAccessCodeConfirmed()
}
}

View file

@ -0,0 +1,12 @@
package com.tangem.features.hotwallet.accesscode.confirm.entity
import com.tangem.features.hotwallet.accesscode.ACCESS_CODE_LENGTH
internal data class ConfirmAccessCodeUM(
val accessCode: String,
val onAccessCodeChange: (String) -> Unit,
val buttonEnabled: Boolean,
val onConfirm: () -> Unit,
) {
val accessCodeLength: Int = ACCESS_CODE_LENGTH
}

View file

@ -0,0 +1,46 @@
package com.tangem.features.hotwallet.accesscode.confirm.ui
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.features.hotwallet.accesscode.ui.AccessCodeEnter
import com.tangem.core.res.R
@Composable
internal fun SetAccessCodeConfirmContent(
accessCode: String,
onAccessCodeChange: (String) -> Unit,
accessCodeLength: Int,
onConfirm: () -> Unit,
buttonEnabled: Boolean,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier
.fillMaxSize()
.navigationBarsPadding(),
) {
AccessCodeEnter(
modifier = Modifier
.padding(top = 16.dp)
.weight(1f),
accessCode = accessCode,
onAccessCodeChange = onAccessCodeChange,
accessCodeLength = accessCodeLength,
reEnterAccessCodeState = true,
)
PrimaryButton(
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
.imePadding(),
text = stringResourceSafe(R.string.common_confirm),
onClick = onConfirm,
enabled = buttonEnabled,
)
}
}

View file

@ -1,7 +1,8 @@
package com.tangem.features.hotwallet.setaccesscode.di
package com.tangem.features.hotwallet.accesscode.di
import com.tangem.core.decompose.model.Model
import com.tangem.features.hotwallet.setaccesscode.SetAccessCodeModel
import com.tangem.features.hotwallet.accesscode.confirm.ConfirmAccessCodeModel
import com.tangem.features.hotwallet.accesscode.set.SetAccessCodeModel
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
@ -11,10 +12,15 @@ import dagger.multibindings.IntoMap
@Module
@InstallIn(SingletonComponent::class)
internal interface SetAccessCodeModule {
internal interface AccessCodeModule {
@Binds
@IntoMap
@ClassKey(SetAccessCodeModel::class)
fun bindSetAccessCodeModel(model: SetAccessCodeModel): Model
@Binds
@IntoMap
@ClassKey(ConfirmAccessCodeModel::class)
fun bindConfirmAccessCodeModel(model: ConfirmAccessCodeModel): Model
}

View file

@ -1,4 +1,4 @@
package com.tangem.features.hotwallet.setaccesscode
package com.tangem.features.hotwallet.accesscode.set
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@ -8,8 +8,9 @@ import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.security.DisableScreenshotsDisposableEffect
import com.tangem.features.hotwallet.setaccesscode.ui.SetAccessCodeContent
import com.tangem.features.hotwallet.accesscode.set.ui.SetAccessCodeContent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
internal class SetAccessCodeComponent @AssistedInject constructor(
@ -23,21 +24,28 @@ internal class SetAccessCodeComponent @AssistedInject constructor(
override fun Content(modifier: Modifier) {
val state by model.uiState.collectAsStateWithLifecycle()
DisableScreenshotsDisposableEffect()
SetAccessCodeContent(
state = state,
onBack = { model.onBack() },
accessCode = state.accessCode,
onAccessCodeChange = state.onAccessCodeChange,
accessCodeLength = state.accessCodeLength,
onContinue = state.onContinue,
buttonEnabled = state.buttonEnabled,
modifier = modifier,
)
DisableScreenshotsDisposableEffect()
}
interface ModelCallbacks {
fun onBackClick()
fun onAccessCodeSet()
fun onAccessCodeSet(accessCode: String)
}
data class Params(
val callbacks: ModelCallbacks,
)
@AssistedFactory
interface Factory {
fun create(context: AppComponentContext, params: Params): SetAccessCodeComponent
}
}

View file

@ -0,0 +1,45 @@
package com.tangem.features.hotwallet.accesscode.set
import androidx.compose.runtime.Stable
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.features.hotwallet.accesscode.set.entity.SetAccessCodeUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import javax.inject.Inject
@Stable
@ModelScoped
internal class SetAccessCodeModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
) : Model() {
private val params = paramsContainer.require<SetAccessCodeComponent.Params>()
internal val uiState: StateFlow<SetAccessCodeUM>
field = MutableStateFlow(getInitialState())
private fun getInitialState() = SetAccessCodeUM(
accessCode = "",
onAccessCodeChange = ::onAccessCodeChange,
buttonEnabled = false,
onContinue = ::onContinue,
)
private fun onAccessCodeChange(value: String) {
uiState.update {
it.copy(
accessCode = value,
buttonEnabled = value.length == uiState.value.accessCodeLength,
)
}
}
private fun onContinue() {
params.callbacks.onAccessCodeSet(uiState.value.accessCode)
}
}

View file

@ -0,0 +1,12 @@
package com.tangem.features.hotwallet.accesscode.set.entity
import com.tangem.features.hotwallet.accesscode.ACCESS_CODE_LENGTH
internal data class SetAccessCodeUM(
val accessCode: String,
val onAccessCodeChange: (String) -> Unit,
val buttonEnabled: Boolean,
val onContinue: () -> Unit,
) {
val accessCodeLength: Int = ACCESS_CODE_LENGTH
}

View file

@ -0,0 +1,46 @@
package com.tangem.features.hotwallet.accesscode.set.ui
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.features.hotwallet.accesscode.ui.AccessCodeEnter
import com.tangem.core.res.R
@Composable
internal fun SetAccessCodeContent(
accessCode: String,
onAccessCodeChange: (String) -> Unit,
accessCodeLength: Int,
onContinue: () -> Unit,
buttonEnabled: Boolean,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier
.fillMaxSize()
.navigationBarsPadding(),
) {
AccessCodeEnter(
modifier = Modifier
.padding(top = 16.dp)
.weight(1f),
accessCode = accessCode,
onAccessCodeChange = onAccessCodeChange,
accessCodeLength = accessCodeLength,
reEnterAccessCodeState = false,
)
PrimaryButton(
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
.imePadding(),
text = stringResourceSafe(R.string.common_continue),
onClick = onContinue,
enabled = buttonEnabled,
)
}
}

View file

@ -1,4 +1,4 @@
package com.tangem.features.hotwallet.setaccesscode.ui
package com.tangem.features.hotwallet.accesscode.ui
import android.content.res.Configuration
import androidx.compose.foundation.background
@ -15,11 +15,12 @@ import com.tangem.core.ui.components.fields.PinTextField
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.hotwallet.setaccesscode.entity.SetAccessCodeUM
@Composable
internal fun SetAccessCodeEnter(
state: SetAccessCodeUM,
internal fun AccessCodeEnter(
accessCode: String,
onAccessCodeChange: (String) -> Unit,
accessCodeLength: Int,
reEnterAccessCodeState: Boolean,
modifier: Modifier = Modifier,
) {
@ -52,7 +53,7 @@ internal fun SetAccessCodeEnter(
} else {
stringResourceSafe(
R.string.access_code_create_description,
state.accessCodeLength,
accessCodeLength,
)
},
style = TangemTheme.typography.body1,
@ -67,18 +68,10 @@ internal fun SetAccessCodeEnter(
contentAlignment = Alignment.Center,
) {
PinTextField(
length = state.accessCodeLength,
length = accessCodeLength,
isPasswordVisual = true,
value = if (reEnterAccessCodeState) {
state.accessCodeSecond
} else {
state.accessCodeFirst
},
onValueChange = if (reEnterAccessCodeState) {
state.onAccessCodeSecondChange
} else {
state.onAccessCodeFirstChange
},
value = accessCode,
onValueChange = onAccessCodeChange,
)
}
}
@ -89,37 +82,25 @@ internal fun SetAccessCodeEnter(
@Composable
private fun Preview() {
TangemThemePreview {
SetAccessCodeEnter(
AccessCodeEnter(
accessCode = "123456",
onAccessCodeChange = {},
accessCodeLength = 6,
reEnterAccessCodeState = false,
state = SetAccessCodeUM(
step = SetAccessCodeUM.Step.AccessCode,
accessCodeFirst = "",
accessCodeSecond = "",
onAccessCodeFirstChange = {},
onAccessCodeSecondChange = {},
buttonEnabled = false,
onContinue = {},
),
)
}
}
@Composable
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun Preview2() {
TangemThemePreview {
SetAccessCodeEnter(
AccessCodeEnter(
accessCode = "123456",
onAccessCodeChange = {},
accessCodeLength = 6,
reEnterAccessCodeState = true,
state = SetAccessCodeUM(
step = SetAccessCodeUM.Step.ConfirmAccessCode,
accessCodeFirst = "",
accessCodeSecond = "",
onAccessCodeFirstChange = {},
onAccessCodeSecondChange = {},
buttonEnabled = false,
onContinue = {},
),
)
}
}

View file

@ -9,11 +9,12 @@ import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.navigation.Router
import com.tangem.domain.settings.ShouldAskPermissionUseCase
import com.tangem.features.hotwallet.setaccesscode.SetAccessCodeComponent
import com.tangem.features.hotwallet.addexistingwallet.start.AddExistingWalletStartComponent
import com.tangem.features.hotwallet.addexistingwallet.im.port.AddExistingWalletImportComponent
import com.tangem.features.hotwallet.addexistingwallet.root.routing.AddExistingWalletRoute
import com.tangem.features.hotwallet.addexistingwallet.start.AddExistingWalletStartComponent
import com.tangem.features.hotwallet.manualbackup.completed.ManualBackupCompletedComponent
import com.tangem.features.hotwallet.accesscode.confirm.ConfirmAccessCodeComponent
import com.tangem.features.hotwallet.accesscode.set.SetAccessCodeComponent
import com.tangem.features.hotwallet.setupfinished.MobileWalletSetupFinishedComponent
import com.tangem.features.pushnotifications.api.PushNotificationsComponent
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
@ -31,20 +32,22 @@ internal class AddExistingWalletModel @Inject constructor(
val addExistingWalletStartModelCallbacks = AddExistingWalletStartModelCallbacks()
val addExistingWalletImportModelCallbacks = AddExistingWalletImportModelCallbacks()
val manualBackupCompletedComponentModelCallbacks = ManualBackupCompletedComponentModelCallbacks()
val accessCodeModelCallbacks = AccessCodeModelCallbacks()
val pushNotificationsComponentModelCallbacks = PushNotificationsComponentModelCallbacks()
val setAccessCodeModelCallbacks = SetAccessCodeModelCallbacks()
val confirmAccessCodeModelCallbacks = ConfirmAccessCodeModelCallbacks()
val mobileWalletSetupFinishedComponentModelCallbacks = MobileWalletSetupFinishedComponentModelCallbacks()
val stackNavigation = StackNavigation<AddExistingWalletRoute>()
fun onChildBack(currentRoute: AddExistingWalletRoute) {
when (currentRoute) {
AddExistingWalletRoute.Import -> stackNavigation.pop()
AddExistingWalletRoute.BackupCompleted -> Unit
AddExistingWalletRoute.AccessCode -> stackNavigation.pop()
AddExistingWalletRoute.PushNotifications -> Unit
AddExistingWalletRoute.SetupFinished -> Unit
AddExistingWalletRoute.Start -> Unit
is AddExistingWalletRoute.Import -> stackNavigation.pop()
is AddExistingWalletRoute.BackupCompleted -> Unit
is AddExistingWalletRoute.ConfirmAccessCode -> stackNavigation.pop()
is AddExistingWalletRoute.SetAccessCode -> stackNavigation.pop()
is AddExistingWalletRoute.PushNotifications -> Unit
is AddExistingWalletRoute.SetupFinished -> Unit
is AddExistingWalletRoute.Start -> Unit
}
}
@ -66,16 +69,18 @@ internal class AddExistingWalletModel @Inject constructor(
inner class ManualBackupCompletedComponentModelCallbacks : ManualBackupCompletedComponent.ModelCallbacks {
override fun onContinueClick() {
stackNavigation.push(AddExistingWalletRoute.AccessCode)
stackNavigation.push(AddExistingWalletRoute.SetAccessCode)
}
}
inner class AccessCodeModelCallbacks : SetAccessCodeComponent.ModelCallbacks {
override fun onBackClick() {
stackNavigation.pop()
inner class SetAccessCodeModelCallbacks : SetAccessCodeComponent.ModelCallbacks {
override fun onAccessCodeSet(accessCode: String) {
stackNavigation.push(AddExistingWalletRoute.ConfirmAccessCode(accessCode))
}
}
override fun onAccessCodeSet() {
inner class ConfirmAccessCodeModelCallbacks : ConfirmAccessCodeComponent.ModelCallbacks {
override fun onAccessCodeConfirmed() {
modelScope.launch {
val shouldRequestPush = shouldAskPermissionUseCase(PUSH_PERMISSION)
if (shouldRequestPush) {
@ -95,7 +100,8 @@ internal class AddExistingWalletModel @Inject constructor(
}
}
inner class MobileWalletSetupFinishedComponentModelCallbacks : MobileWalletSetupFinishedComponent.ModelCallbacks {
inner class MobileWalletSetupFinishedComponentModelCallbacks :
MobileWalletSetupFinishedComponent.ModelCallbacks {
override fun onContinueClick() {
router.replaceAll(AppRoute.Wallet)
}

View file

@ -2,7 +2,8 @@ package com.tangem.features.hotwallet.addexistingwallet.root.routing
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.features.hotwallet.setaccesscode.SetAccessCodeComponent
import com.tangem.features.hotwallet.accesscode.set.SetAccessCodeComponent
import com.tangem.features.hotwallet.accesscode.confirm.ConfirmAccessCodeComponent
import com.tangem.features.hotwallet.addexistingwallet.root.AddExistingWalletModel
import com.tangem.features.hotwallet.addexistingwallet.start.AddExistingWalletStartComponent
import com.tangem.features.hotwallet.addexistingwallet.im.port.AddExistingWalletImportComponent
@ -13,6 +14,8 @@ import javax.inject.Inject
internal class AddExistingWalletChildFactory @Inject constructor(
private val pushNotificationsComponent: PushNotificationsComponent.Factory,
private val setAccessCodeSetComponentFactory: SetAccessCodeComponent.Factory,
private val confirmAccessCodeComponentFactory: ConfirmAccessCodeComponent.Factory,
) {
fun createChild(
@ -39,10 +42,17 @@ internal class AddExistingWalletChildFactory @Inject constructor(
callbacks = model.manualBackupCompletedComponentModelCallbacks,
),
)
is AddExistingWalletRoute.AccessCode -> SetAccessCodeComponent(
is AddExistingWalletRoute.SetAccessCode -> setAccessCodeSetComponentFactory.create(
context = childContext,
params = SetAccessCodeComponent.Params(
callbacks = model.accessCodeModelCallbacks,
callbacks = model.setAccessCodeModelCallbacks,
),
)
is AddExistingWalletRoute.ConfirmAccessCode -> confirmAccessCodeComponentFactory.create(
context = childContext,
params = ConfirmAccessCodeComponent.Params(
accessCodeToConfirm = route.accessCode,
callbacks = model.confirmAccessCodeModelCallbacks,
),
)
is AddExistingWalletRoute.PushNotifications -> pushNotificationsComponent.create(
@ -51,7 +61,7 @@ internal class AddExistingWalletChildFactory @Inject constructor(
callbacks = model.pushNotificationsComponentModelCallbacks,
),
)
AddExistingWalletRoute.SetupFinished -> MobileWalletSetupFinishedComponent(
is AddExistingWalletRoute.SetupFinished -> MobileWalletSetupFinishedComponent(
context = childContext,
params = MobileWalletSetupFinishedComponent.Params(
callbacks = model.mobileWalletSetupFinishedComponentModelCallbacks,

View file

@ -15,7 +15,10 @@ internal sealed class AddExistingWalletRoute : Route {
object BackupCompleted : AddExistingWalletRoute()
@Serializable
object AccessCode : AddExistingWalletRoute()
object SetAccessCode : AddExistingWalletRoute()
@Serializable
data class ConfirmAccessCode(val accessCode: String) : AddExistingWalletRoute()
@Serializable
object PushNotifications : AddExistingWalletRoute()

View file

@ -1,84 +0,0 @@
package com.tangem.features.hotwallet.setaccesscode
import androidx.compose.runtime.Stable
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.features.hotwallet.setaccesscode.entity.SetAccessCodeUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import javax.inject.Inject
@Stable
@ModelScoped
internal class SetAccessCodeModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
) : Model() {
private val params = paramsContainer.require<SetAccessCodeComponent.Params>()
internal val uiState: StateFlow<SetAccessCodeUM>
field = MutableStateFlow(getInitialState())
fun onBack() {
when (uiState.value.step) {
SetAccessCodeUM.Step.AccessCode -> {
params.callbacks.onBackClick()
}
SetAccessCodeUM.Step.ConfirmAccessCode -> {
uiState.update {
it.copy(
step = SetAccessCodeUM.Step.AccessCode,
accessCodeSecond = "",
)
}
}
}
}
private fun getInitialState() = SetAccessCodeUM(
step = SetAccessCodeUM.Step.AccessCode,
accessCodeFirst = "",
accessCodeSecond = "",
onAccessCodeFirstChange = ::onAccessCodeFirstChange,
onAccessCodeSecondChange = ::onAccessCodeSecondChange,
buttonEnabled = false,
onContinue = ::onContinue,
)
private fun onAccessCodeFirstChange(value: String) {
uiState.update {
it.copy(
accessCodeFirst = value,
buttonEnabled = value.length == uiState.value.accessCodeLength,
)
}
}
private fun onAccessCodeSecondChange(value: String) {
uiState.update {
it.copy(
accessCodeSecond = value,
buttonEnabled = uiState.value.accessCodeFirst == uiState.value.accessCodeSecond,
)
}
}
private fun onContinue() {
when (uiState.value.step) {
SetAccessCodeUM.Step.AccessCode -> {
uiState.update {
it.copy(
step = SetAccessCodeUM.Step.ConfirmAccessCode,
)
}
}
SetAccessCodeUM.Step.ConfirmAccessCode -> {
params.callbacks.onAccessCodeSet()
}
}
}
}

View file

@ -1,22 +0,0 @@
package com.tangem.features.hotwallet.setaccesscode.entity
internal data class SetAccessCodeUM(
val step: Step,
val accessCodeFirst: String,
val accessCodeSecond: String,
val onAccessCodeFirstChange: (String) -> Unit,
val onAccessCodeSecondChange: (String) -> Unit,
val buttonEnabled: Boolean,
val onContinue: () -> Unit,
) {
val accessCodeLength: Int = ACCESS_CODE_LENGTH
enum class Step {
AccessCode,
ConfirmAccessCode,
}
companion object {
private const val ACCESS_CODE_LENGTH = 6
}
}

View file

@ -1,59 +0,0 @@
package com.tangem.features.hotwallet.setaccesscode.ui
import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedContent
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemAnimations
import com.tangem.features.hotwallet.setaccesscode.entity.SetAccessCodeUM
import com.tangem.features.hotwallet.setaccesscode.entity.SetAccessCodeUM.Step.*
import com.tangem.core.res.R
@Composable
internal fun SetAccessCodeContent(state: SetAccessCodeUM, onBack: () -> Unit, modifier: Modifier = Modifier) {
BackHandler(onBack = onBack)
Column(
modifier = modifier
.fillMaxSize()
.navigationBarsPadding(),
) {
AnimatedContent(
modifier = Modifier.weight(1f),
targetState = state.step,
transitionSpec = TangemAnimations.AnimatedContent
.slide { initial, target -> target.ordinal > initial.ordinal },
label = "AnimatedContent",
) { step ->
when (step) {
AccessCode -> SetAccessCodeEnter(
modifier = Modifier.padding(top = 16.dp),
state = state,
reEnterAccessCodeState = false,
)
ConfirmAccessCode -> SetAccessCodeEnter(
modifier = Modifier.padding(top = 16.dp),
state = state,
reEnterAccessCodeState = true,
)
}
}
PrimaryButton(
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
.imePadding(),
text = if (state.step == ConfirmAccessCode) {
stringResourceSafe(R.string.common_confirm)
} else {
stringResourceSafe(R.string.common_continue)
},
onClick = state.onContinue,
)
}
}