feat: implement import mode in authentication flow and update UI accordingly

This commit is contained in:
2026-02-14 04:04:23 +05:00
parent 85e894182a
commit e301478d92
4 changed files with 65 additions and 15 deletions

View File

@@ -42,6 +42,7 @@ fun AuthFlow(
) )
} }
var showCreateModal by remember { mutableStateOf(false) } var showCreateModal by remember { mutableStateOf(false) }
var isImportMode by remember { mutableStateOf(false) }
// Handle system back button // Handle system back button
BackHandler(enabled = currentScreen != AuthScreen.UNLOCK && !(currentScreen == AuthScreen.WELCOME && !hasExistingAccount)) { BackHandler(enabled = currentScreen != AuthScreen.UNLOCK && !(currentScreen == AuthScreen.WELCOME && !hasExistingAccount)) {
@@ -54,10 +55,22 @@ fun AuthFlow(
} }
AuthScreen.CONFIRM_SEED -> currentScreen = AuthScreen.SEED_PHRASE AuthScreen.CONFIRM_SEED -> currentScreen = AuthScreen.SEED_PHRASE
AuthScreen.SET_PASSWORD -> { AuthScreen.SET_PASSWORD -> {
currentScreen = if (hasExistingAccount) AuthScreen.UNLOCK else AuthScreen.CONFIRM_SEED if (isImportMode) {
currentScreen = AuthScreen.IMPORT_SEED
} else if (hasExistingAccount) {
currentScreen = AuthScreen.UNLOCK
} else {
currentScreen = AuthScreen.CONFIRM_SEED
}
} }
AuthScreen.IMPORT_SEED -> { AuthScreen.IMPORT_SEED -> {
currentScreen = if (hasExistingAccount) AuthScreen.WELCOME else AuthScreen.WELCOME if (isImportMode && hasExistingAccount) {
// Came from UnlockScreen recover — go back to unlock
currentScreen = AuthScreen.UNLOCK
isImportMode = false
} else {
currentScreen = AuthScreen.WELCOME
}
} }
else -> {} // UNLOCK doesn't have back navigation else -> {} // UNLOCK doesn't have back navigation
} }
@@ -129,9 +142,11 @@ fun AuthFlow(
SetPasswordScreen( SetPasswordScreen(
seedPhrase = seedPhrase, seedPhrase = seedPhrase,
isDarkTheme = isDarkTheme, isDarkTheme = isDarkTheme,
isImportMode = isImportMode,
onBack = { onBack = {
// If there are existing accounts, allow going back to unlock screen if (isImportMode) {
if (hasExistingAccount) { currentScreen = AuthScreen.IMPORT_SEED
} else if (hasExistingAccount) {
currentScreen = AuthScreen.UNLOCK currentScreen = AuthScreen.UNLOCK
} else { } else {
currentScreen = AuthScreen.CONFIRM_SEED currentScreen = AuthScreen.CONFIRM_SEED
@@ -144,7 +159,14 @@ fun AuthFlow(
AuthScreen.IMPORT_SEED -> { AuthScreen.IMPORT_SEED -> {
ImportSeedPhraseScreen( ImportSeedPhraseScreen(
isDarkTheme = isDarkTheme, isDarkTheme = isDarkTheme,
onBack = { currentScreen = AuthScreen.WELCOME }, onBack = {
if (isImportMode && hasExistingAccount) {
currentScreen = AuthScreen.UNLOCK
isImportMode = false
} else {
currentScreen = AuthScreen.WELCOME
}
},
onSeedPhraseImported = { words -> onSeedPhraseImported = { words ->
seedPhrase = words seedPhrase = words
currentScreen = AuthScreen.SET_PASSWORD currentScreen = AuthScreen.SET_PASSWORD
@@ -160,7 +182,13 @@ fun AuthFlow(
onSwitchAccount = { onSwitchAccount = {
// Navigate to create new account screen // Navigate to create new account screen
// Don't reset selectedAccountId so last logged account is remembered // Don't reset selectedAccountId so last logged account is remembered
isImportMode = false
currentScreen = AuthScreen.WELCOME currentScreen = AuthScreen.WELCOME
},
onRecover = {
// Go directly to seed import (like Desktop's "recover your password")
isImportMode = true
currentScreen = AuthScreen.IMPORT_SEED
} }
) )
} }

View File

@@ -38,6 +38,7 @@ import kotlinx.coroutines.launch
fun SetPasswordScreen( fun SetPasswordScreen(
seedPhrase: List<String>, seedPhrase: List<String>,
isDarkTheme: Boolean, isDarkTheme: Boolean,
isImportMode: Boolean = false,
onBack: () -> Unit, onBack: () -> Unit,
onAccountCreated: (DecryptedAccount) -> Unit onAccountCreated: (DecryptedAccount) -> Unit
) { ) {
@@ -191,7 +192,7 @@ fun SetPasswordScreen(
enter = fadeIn(tween(400, delayMillis = 100)) enter = fadeIn(tween(400, delayMillis = 100))
) { ) {
Text( Text(
text = "Protect Your Account", text = if (isImportMode) "Recover Account" else "Protect Your Account",
fontSize = if (isKeyboardVisible) 20.sp else 24.sp, fontSize = if (isKeyboardVisible) 20.sp else 24.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = textColor color = textColor
@@ -205,7 +206,9 @@ fun SetPasswordScreen(
enter = fadeIn(tween(500, delayMillis = 200)) enter = fadeIn(tween(500, delayMillis = 200))
) { ) {
Text( Text(
text = text = if (isImportMode)
"Set a password to protect your recovered account.\nYou'll need it to unlock Rosetta."
else
"This password encrypts your keys locally.\nYou'll need it to unlock Rosetta.", "This password encrypts your keys locally.\nYou'll need it to unlock Rosetta.",
fontSize = if (isKeyboardVisible) 12.sp else 14.sp, fontSize = if (isKeyboardVisible) 12.sp else 14.sp,
color = secondaryTextColor, color = secondaryTextColor,
@@ -568,7 +571,7 @@ fun SetPasswordScreen(
) )
} else { } else {
Text( Text(
text = "Create Account", text = if (isImportMode) "Recover Account" else "Create Account",
fontSize = 16.sp, fontSize = 16.sp,
fontWeight = FontWeight.SemiBold fontWeight = FontWeight.SemiBold
) )

View File

@@ -156,7 +156,8 @@ fun UnlockScreen(
isDarkTheme: Boolean, isDarkTheme: Boolean,
selectedAccountId: String? = null, selectedAccountId: String? = null,
onUnlocked: (DecryptedAccount) -> Unit, onUnlocked: (DecryptedAccount) -> Unit,
onSwitchAccount: () -> Unit = {} onSwitchAccount: () -> Unit = {},
onRecover: () -> Unit = {}
) { ) {
val themeAnimSpec = val themeAnimSpec =
tween<Color>(durationMillis = 500, easing = CubicBezierEasing(0.4f, 0f, 0.2f, 1f)) tween<Color>(durationMillis = 500, easing = CubicBezierEasing(0.4f, 0f, 0.2f, 1f))
@@ -716,23 +717,41 @@ fun UnlockScreen(
) )
} }
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(16.dp))
TextButton(onClick = onSwitchAccount) { TextButton(onClick = onRecover) {
Icon( Icon(
painter = TelegramIcons.AddContact, painter = TelegramIcons.Unlock,
contentDescription = null, contentDescription = null,
tint = PrimaryBlue, tint = PrimaryBlue,
modifier = Modifier.size(18.dp) modifier = Modifier.size(18.dp)
) )
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text( Text(
text = "Create or import account", text = "Recover account",
color = PrimaryBlue, color = PrimaryBlue,
fontSize = 15.sp, fontSize = 15.sp,
fontWeight = FontWeight.Medium fontWeight = FontWeight.Medium
) )
} }
Spacer(modifier = Modifier.height(4.dp))
TextButton(onClick = onSwitchAccount) {
Icon(
painter = TelegramIcons.AddContact,
contentDescription = null,
tint = secondaryTextColor,
modifier = Modifier.size(18.dp)
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = "Create new account",
color = secondaryTextColor,
fontSize = 14.sp,
fontWeight = FontWeight.Normal
)
}
} }
} }
} }

View File

@@ -1014,7 +1014,7 @@ fun ProfileScreen(
clip = false clip = false
) )
.clip(CircleShape) .clip(CircleShape)
.background(if (isDarkTheme) Color(0xFF2C2C2E) else PrimaryBlue) .background(if (isDarkTheme) Color(0xFF2A2A2A) else Color(0xFF0D8CF4))
.clickable { showPhotoPicker = true }, .clickable { showPhotoPicker = true },
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
@@ -1795,7 +1795,7 @@ fun TelegramToggleItem(
val textColor = if (isDarkTheme) Color.White else Color.Black val textColor = if (isDarkTheme) Color.White else Color.Black
val secondaryTextColor = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666) val secondaryTextColor = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666)
val iconColor = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666) val iconColor = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666)
val accentColor = if (isDarkTheme) PrimaryBlueDark else PrimaryBlue val accentColor = if (isDarkTheme) Color(0xFF2A2A2A) else Color(0xFF0D8CF4)
val dividerColor = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE0E0E0) val dividerColor = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE0E0E0)
Column { Column {