Updated on 2026-08-14

This commit is contained in:
Tangem 2025-09-22 18:18:01 +03:00
parent 57ac29d594
commit 404daaa085
6 changed files with 189 additions and 85 deletions

View file

@ -5,7 +5,7 @@ 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.components.FullScreen
import com.tangem.core.ui.components.DialogFullScreen
import com.tangem.domain.wallets.hot.HotWalletPasswordRequester
import com.tangem.features.hotwallet.HotAccessCodeRequestComponent
import com.tangem.features.hotwallet.accesscoderequest.ui.HotAccessCodeRequestFullScreenContent
@ -47,7 +47,7 @@ internal class DefaultHotAccessCodeRequestComponent @AssistedInject constructor(
var isShownIfProxy by remember { mutableStateOf(state.isShown) }
if (isShownIfProxy) {
FullScreen(focusable = true, onBackClick = state.onDismiss) {
DialogFullScreen(onDismissRequest = state.onDismiss) {
HotAccessCodeRequestFullScreenContent(
state = state.copy(isShown = isShownProxy),
modifier = modifier,

View file

@ -82,6 +82,7 @@ internal class HotAccessCodeRequestModel @Inject constructor(
it.copy(
accessCodeColor = PinTextColor.WrongCode,
onAccessCodeChange = {},
useBiometricVisible = currentRequest.hasBiometry,
)
}
delay(timeMillis = 500) // Delay to show the wrong access code state
@ -121,7 +122,10 @@ internal class HotAccessCodeRequestModel @Inject constructor(
if (accessCode.length == ACCESS_CODE_LENGTH) {
uiState.update {
it.copy(onAccessCodeChange = {})
it.copy(
onAccessCodeChange = {},
useBiometricVisible = false,
)
}
result.value = HotWalletPasswordRequester.Result.EnteredPassword(HotAuth.Password(accessCode.toCharArray()))

View file

@ -37,105 +37,110 @@ import com.tangem.features.hotwallet.impl.R
@Suppress("MagicNumber", "LongMethod")
@Composable
internal fun HotAccessCodeRequestFullScreenContent(state: HotAccessCodeRequestUM, modifier: Modifier = Modifier) {
AnimatedVisibility(
modifier = modifier,
visible = state.isShown,
enter = fadeIn(),
exit = fadeOut(),
) {
Column(
Modifier
.fillMaxSize()
.background(TangemTheme.colors.background.primary),
horizontalAlignment = Alignment.CenterHorizontally,
Box(Modifier.fillMaxSize()) {
AnimatedVisibility(
modifier = modifier,
visible = state.isShown,
enter = fadeIn(),
exit = fadeOut(),
) {
TangemTopAppBar(
modifier = Modifier
.statusBarsPadding(),
startButton = TopAppBarButtonUM.Back(state.onDismiss),
)
SpacerH(68.dp)
Column(
Modifier
.weight(1f)
.fillMaxWidth()
.padding(horizontal = 24.dp),
.fillMaxSize()
.background(TangemTheme.colors.background.primary),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
modifier = Modifier.animateEnterExit(
enter = slideInVertically(
tween(),
initialOffsetY = { it + 200 },
) + fadeIn(tween()),
exit = slideOutVertically(tween(300)) { it - 200 } + fadeOut(tween()),
),
text = stringResourceSafe(R.string.access_code_check_title),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
TangemTopAppBar(
modifier = Modifier.statusBarsPadding(),
startButton = TopAppBarButtonUM.Back(state.onDismiss),
)
SpacerH24()
SpacerH(68.dp)
PinTextField(
modifier = Modifier.animateEnterExit(
enter = slideInVertically(
tween(),
initialOffsetY = { it + 200 },
) + fadeIn(tween()),
exit = slideOutVertically(tween(300)) { it - 200 } + fadeOut(tween()),
),
length = 6,
isPasswordVisual = true,
value = state.accessCode,
pinTextColor = state.accessCodeColor,
onValueChange = state.onAccessCodeChange,
)
Column(
Modifier
.weight(1f)
.fillMaxWidth()
.padding(horizontal = 24.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
modifier = Modifier.animateEnterExit(
enter = slideInVertically(
tween(),
initialOffsetY = { it + 200 },
) + fadeIn(tween()),
exit = slideOutVertically(tween(300)) { it - 200 } + fadeOut(tween()),
),
text = stringResourceSafe(R.string.access_code_check_title),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
)
SpacerH(20.dp)
SpacerH24()
PinTextField(
modifier = Modifier.animateEnterExit(
enter = slideInVertically(
tween(),
initialOffsetY = { it + 200 },
) + fadeIn(tween()),
exit = slideOutVertically(tween(300)) { it - 200 } + fadeOut(tween()),
),
length = 6,
isPasswordVisual = true,
value = state.accessCode,
pinTextColor = state.accessCodeColor,
onValueChange = state.onAccessCodeChange,
)
SpacerH(20.dp)
AnimatedVisibility(
modifier = Modifier.animateEnterExit(
enter = slideInVertically(
tween(),
initialOffsetY = { it + 200 },
) + fadeIn(tween()),
exit = slideOutVertically(tween(300)) { it - 200 } + fadeOut(tween()),
),
visible = state.wrongAccessCodeText != null,
enter = fadeIn(),
exit = fadeOut(),
) {
val wrongAccessCodeText =
state.wrongAccessCodeText ?: return@AnimatedVisibility
Text(
text = wrongAccessCodeText.resolveReference(),
textAlign = TextAlign.Center,
style = TangemTheme.typography.caption2.copy(
lineBreak = LineBreak.Heading,
),
color = TangemTheme.colors.text.warning,
)
}
}
AnimatedVisibility(
modifier = Modifier.animateEnterExit(
enter = slideInVertically(
tween(),
initialOffsetY = { it + 200 },
) + fadeIn(tween()),
exit = slideOutVertically(tween(300)) { it - 200 } + fadeOut(tween()),
),
visible = state.wrongAccessCodeText != null,
visible = state.useBiometricVisible,
enter = fadeIn(),
exit = fadeOut(),
) {
val wrongAccessCodeText =
state.wrongAccessCodeText ?: return@AnimatedVisibility
Text(
text = wrongAccessCodeText.resolveReference(),
textAlign = TextAlign.Center,
style = TangemTheme.typography.caption2.copy(
lineBreak = LineBreak.Heading,
SecondaryButton(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
.navigationBarsPadding()
.imePadding(),
text = stringResourceSafe(
id = R.string.welcome_unlock,
stringResourceSafe(R.string.common_biometrics),
),
color = TangemTheme.colors.text.warning,
onClick = state.useBiometricClick,
)
}
}
if (state.useBiometricVisible) {
SecondaryButton(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
.navigationBarsPadding()
.imePadding(),
text = stringResourceSafe(
id = R.string.welcome_unlock,
stringResourceSafe(R.string.common_biometrics),
),
onClick = state.useBiometricClick,
)
}
}
}