feat: Simplify animations across multiple screens by replacing slide transitions with fade animations for improved user experience
This commit is contained in:
@@ -159,10 +159,7 @@ fun ConfirmSeedPhraseScreen(
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(250)) + slideInVertically(
|
||||
initialOffsetY = { -40 },
|
||||
animationSpec = tween(250)
|
||||
)
|
||||
enter = fadeIn(tween(300))
|
||||
) {
|
||||
Text(
|
||||
text = "Confirm Backup",
|
||||
@@ -176,10 +173,7 @@ fun ConfirmSeedPhraseScreen(
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(500, delayMillis = 100)) + slideInVertically(
|
||||
initialOffsetY = { -20 },
|
||||
animationSpec = tween(500, delayMillis = 100)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 100))
|
||||
) {
|
||||
Text(
|
||||
text = "Enter words #${wordsToConfirm[0].first + 1}, #${wordsToConfirm[1].first + 1}, #${wordsToConfirm[2].first + 1}, #${wordsToConfirm[3].first + 1}\nto confirm you've backed up your phrase.",
|
||||
@@ -354,10 +348,7 @@ fun ConfirmSeedPhraseScreen(
|
||||
// Continue Button
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(500, delayMillis = 600)) + slideInVertically(
|
||||
initialOffsetY = { 50 },
|
||||
animationSpec = tween(500, delayMillis = 600)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 600))
|
||||
) {
|
||||
Button(
|
||||
onClick = {
|
||||
@@ -408,10 +399,7 @@ private fun AnimatedConfirmWordItem(
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(400, delayMillis = delay)) + slideInHorizontally(
|
||||
initialOffsetX = { if (number <= 6) -50 else 50 },
|
||||
animationSpec = tween(400, delayMillis = delay)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = delay))
|
||||
) {
|
||||
if (isInput) {
|
||||
ConfirmWordInputItem(
|
||||
|
||||
@@ -78,10 +78,7 @@ fun ImportSeedPhraseScreen(
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(250)) + slideInVertically(
|
||||
initialOffsetY = { -40 },
|
||||
animationSpec = tween(250)
|
||||
)
|
||||
enter = fadeIn(tween(300))
|
||||
) {
|
||||
Text(
|
||||
text = "Import Account",
|
||||
@@ -95,10 +92,7 @@ fun ImportSeedPhraseScreen(
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(500, delayMillis = 100)) + slideInVertically(
|
||||
initialOffsetY = { -20 },
|
||||
animationSpec = tween(500, delayMillis = 100)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 100))
|
||||
) {
|
||||
Text(
|
||||
text = "Enter your 12-word recovery phrase\nto restore your account.",
|
||||
@@ -243,10 +237,7 @@ fun ImportSeedPhraseScreen(
|
||||
// Import button
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(500, delayMillis = 600)) + slideInVertically(
|
||||
initialOffsetY = { 50 },
|
||||
animationSpec = tween(500, delayMillis = 600)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 600))
|
||||
) {
|
||||
Button(
|
||||
onClick = {
|
||||
@@ -302,10 +293,7 @@ private fun AnimatedWordInputItem(
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(400, delayMillis = delay)) + slideInHorizontally(
|
||||
initialOffsetX = { if (number <= 6) -50 else 50 },
|
||||
animationSpec = tween(400, delayMillis = delay)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = delay))
|
||||
) {
|
||||
WordInputItem(
|
||||
number = number,
|
||||
|
||||
@@ -80,10 +80,7 @@ fun SeedPhraseScreen(
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(250)) + slideInVertically(
|
||||
initialOffsetY = { -40 },
|
||||
animationSpec = tween(250)
|
||||
)
|
||||
enter = fadeIn(tween(300))
|
||||
) {
|
||||
Text(
|
||||
text = "Your Recovery Phrase",
|
||||
@@ -97,10 +94,7 @@ fun SeedPhraseScreen(
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(500, delayMillis = 100)) + slideInVertically(
|
||||
initialOffsetY = { -20 },
|
||||
animationSpec = tween(500, delayMillis = 100)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 100))
|
||||
) {
|
||||
Text(
|
||||
text = "Write down these 12 words in order.\nYou'll need them to restore your account.",
|
||||
@@ -213,10 +207,7 @@ fun SeedPhraseScreen(
|
||||
// Continue button
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(500, delayMillis = 700)) + slideInVertically(
|
||||
initialOffsetY = { 50 },
|
||||
animationSpec = tween(500, delayMillis = 700)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 700))
|
||||
) {
|
||||
Button(
|
||||
onClick = { onConfirm(seedPhrase) },
|
||||
@@ -313,10 +304,7 @@ private fun AnimatedWordItem(
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(400, delayMillis = delay)) + slideInHorizontally(
|
||||
initialOffsetX = { if (number <= 6) -50 else 50 },
|
||||
animationSpec = tween(400, delayMillis = delay)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = delay))
|
||||
) {
|
||||
WordItem(
|
||||
number = number,
|
||||
|
||||
@@ -103,10 +103,7 @@ fun SelectAccountScreen(
|
||||
// Header
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(250)) + slideInVertically(
|
||||
initialOffsetY = { -40 },
|
||||
animationSpec = tween(250)
|
||||
)
|
||||
enter = fadeIn(tween(300))
|
||||
) {
|
||||
Column {
|
||||
Row {
|
||||
@@ -269,10 +266,7 @@ private fun AccountListItem(
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(200)) + slideInHorizontally(
|
||||
initialOffsetX = { 50 },
|
||||
animationSpec = tween(200)
|
||||
)
|
||||
enter = fadeIn(tween(300))
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
@@ -378,10 +372,7 @@ private fun AddAccountButton(
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn(tween(200)) + slideInHorizontally(
|
||||
initialOffsetX = { -50 },
|
||||
animationSpec = tween(200)
|
||||
)
|
||||
enter = fadeIn(tween(300))
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
|
||||
@@ -178,12 +178,7 @@ fun SetPasswordScreen(
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter =
|
||||
fadeIn(tween(500, delayMillis = 100)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { -20 },
|
||||
animationSpec = tween(500, delayMillis = 100)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 100))
|
||||
) {
|
||||
Text(
|
||||
text = "Protect Your Account",
|
||||
@@ -214,12 +209,7 @@ fun SetPasswordScreen(
|
||||
// Password Field
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter =
|
||||
fadeIn(tween(500, delayMillis = 300)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { 50 },
|
||||
animationSpec = tween(500, delayMillis = 300)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 300))
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = password,
|
||||
@@ -270,12 +260,7 @@ fun SetPasswordScreen(
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter =
|
||||
fadeIn(tween(400, delayMillis = 350)) +
|
||||
slideInHorizontally(
|
||||
initialOffsetX = { -30 },
|
||||
animationSpec = tween(400, delayMillis = 350)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 350))
|
||||
) {
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
Row(
|
||||
@@ -345,12 +330,7 @@ fun SetPasswordScreen(
|
||||
// Confirm Password Field
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter =
|
||||
fadeIn(tween(500, delayMillis = 400)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { 50 },
|
||||
animationSpec = tween(500, delayMillis = 400)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 400))
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = confirmPassword,
|
||||
@@ -407,12 +387,7 @@ fun SetPasswordScreen(
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter =
|
||||
fadeIn(tween(400, delayMillis = 450)) +
|
||||
slideInHorizontally(
|
||||
initialOffsetX = { -30 },
|
||||
animationSpec = tween(400, delayMillis = 450)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 450))
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@@ -459,20 +434,8 @@ fun SetPasswordScreen(
|
||||
// Info - hide when keyboard is visible
|
||||
AnimatedVisibility(
|
||||
visible = visible && !isKeyboardVisible,
|
||||
enter =
|
||||
fadeIn(tween(200)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { 30 },
|
||||
animationSpec = tween(200)
|
||||
) +
|
||||
scaleIn(initialScale = 0.9f, animationSpec = tween(200)),
|
||||
exit =
|
||||
fadeOut(tween(150)) +
|
||||
slideOutVertically(
|
||||
targetOffsetY = { 30 },
|
||||
animationSpec = tween(150)
|
||||
) +
|
||||
scaleOut(targetScale = 0.9f, animationSpec = tween(150))
|
||||
enter = fadeIn(tween(300)),
|
||||
exit = fadeOut(tween(200))
|
||||
) {
|
||||
Row(
|
||||
modifier =
|
||||
@@ -504,12 +467,7 @@ fun SetPasswordScreen(
|
||||
// Create Account Button
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter =
|
||||
fadeIn(tween(500, delayMillis = 600)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { 50 },
|
||||
animationSpec = tween(500, delayMillis = 600)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 600))
|
||||
) {
|
||||
Button(
|
||||
onClick = {
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.rosetta.messenger.data.AccountManager
|
||||
import com.rosetta.messenger.data.DecryptedAccount
|
||||
import com.rosetta.messenger.data.EncryptedAccount
|
||||
import com.rosetta.messenger.network.ProtocolManager
|
||||
import com.rosetta.messenger.network.ProtocolState
|
||||
import com.rosetta.messenger.ui.chats.getAvatarColor
|
||||
import com.rosetta.messenger.ui.chats.getAvatarText
|
||||
import com.rosetta.messenger.ui.onboarding.PrimaryBlue
|
||||
@@ -195,12 +196,7 @@ fun UnlockScreen(
|
||||
// Title
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter =
|
||||
fadeIn(tween(600, delayMillis = 200)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { 30 },
|
||||
animationSpec = tween(600, delayMillis = 200)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 200))
|
||||
) {
|
||||
Text(
|
||||
text = "Welcome Back",
|
||||
@@ -226,12 +222,7 @@ fun UnlockScreen(
|
||||
// Account Selector Card
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter =
|
||||
fadeIn(tween(600, delayMillis = 350)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { 50 },
|
||||
animationSpec = tween(600, delayMillis = 350)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 350))
|
||||
) {
|
||||
Column {
|
||||
// Account selector dropdown
|
||||
@@ -511,12 +502,7 @@ fun UnlockScreen(
|
||||
// Password Field
|
||||
AnimatedVisibility(
|
||||
visible = visible && !isDropdownExpanded,
|
||||
enter =
|
||||
fadeIn(tween(600, delayMillis = 400)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { 50 },
|
||||
animationSpec = tween(600, delayMillis = 400)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 400))
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = password,
|
||||
@@ -566,8 +552,8 @@ fun UnlockScreen(
|
||||
// Error message
|
||||
AnimatedVisibility(
|
||||
visible = error != null,
|
||||
enter = fadeIn() + slideInVertically { -10 },
|
||||
exit = fadeOut()
|
||||
enter = fadeIn(tween(200)),
|
||||
exit = fadeOut(tween(150))
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(text = error ?: "", fontSize = 14.sp, color = Color(0xFFE53935))
|
||||
@@ -578,12 +564,7 @@ fun UnlockScreen(
|
||||
// Unlock Button
|
||||
AnimatedVisibility(
|
||||
visible = visible && !isDropdownExpanded,
|
||||
enter =
|
||||
fadeIn(tween(600, delayMillis = 500)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { 50 },
|
||||
animationSpec = tween(600, delayMillis = 500)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 500))
|
||||
) {
|
||||
Button(
|
||||
onClick = {
|
||||
@@ -636,13 +617,37 @@ fun UnlockScreen(
|
||||
name = account.name
|
||||
)
|
||||
|
||||
android.util.Log.d("UnlockScreen", "🔐 Starting connection and authentication...")
|
||||
android.util.Log.d("UnlockScreen", " PublicKey: ${account.publicKey.take(16)}...")
|
||||
android.util.Log.d("UnlockScreen", " PrivateKeyHash: ${privateKeyHash.take(16)}...")
|
||||
|
||||
// Connect to server and authenticate
|
||||
ProtocolManager.connect()
|
||||
// Give WebSocket time to connect before authenticating
|
||||
kotlinx.coroutines.delay(500)
|
||||
|
||||
// 🔥 Ждем пока websocket подключится (CONNECTED state)
|
||||
var waitAttempts = 0
|
||||
while (ProtocolManager.state.value == ProtocolState.DISCONNECTED && waitAttempts < 50) {
|
||||
kotlinx.coroutines.delay(100)
|
||||
waitAttempts++
|
||||
}
|
||||
|
||||
android.util.Log.d("UnlockScreen", "🔌 Connection state after wait: ${ProtocolManager.state.value}")
|
||||
|
||||
if (ProtocolManager.state.value == ProtocolState.DISCONNECTED) {
|
||||
error = "Failed to connect to server"
|
||||
isUnlocking = false
|
||||
return@launch
|
||||
}
|
||||
|
||||
// Еще немного ждем для стабильности
|
||||
kotlinx.coroutines.delay(300)
|
||||
|
||||
android.util.Log.d("UnlockScreen", "🔐 Starting authentication...")
|
||||
ProtocolManager.authenticate(account.publicKey, privateKeyHash)
|
||||
|
||||
accountManager.setCurrentAccount(account.publicKey)
|
||||
|
||||
android.util.Log.d("UnlockScreen", "✅ Unlock complete, calling onUnlocked callback")
|
||||
onUnlocked(decryptedAccount)
|
||||
} catch (e: Exception) {
|
||||
error = "Failed to unlock: \${e.message}"
|
||||
@@ -684,12 +689,7 @@ fun UnlockScreen(
|
||||
// Create New Account button
|
||||
AnimatedVisibility(
|
||||
visible = visible && !isDropdownExpanded,
|
||||
enter =
|
||||
fadeIn(tween(600, delayMillis = 600)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { 50 },
|
||||
animationSpec = tween(600, delayMillis = 600)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 600))
|
||||
) {
|
||||
TextButton(onClick = onSwitchAccount) {
|
||||
Icon(
|
||||
|
||||
@@ -115,12 +115,7 @@ fun WelcomeScreen(
|
||||
// Title
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter =
|
||||
fadeIn(tween(600, delayMillis = 200)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { 50 },
|
||||
animationSpec = tween(600, delayMillis = 200)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 200))
|
||||
) {
|
||||
Text(
|
||||
text = "Your Keys,\nYour Messages",
|
||||
@@ -137,12 +132,7 @@ fun WelcomeScreen(
|
||||
// Subtitle
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter =
|
||||
fadeIn(tween(600, delayMillis = 300)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { 50 },
|
||||
animationSpec = tween(600, delayMillis = 300)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 300))
|
||||
) {
|
||||
Text(
|
||||
text = "Secure messaging with\ncryptographic keys",
|
||||
@@ -188,12 +178,7 @@ fun WelcomeScreen(
|
||||
// Create Seed Button
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter =
|
||||
fadeIn(tween(600, delayMillis = 500)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { 100 },
|
||||
animationSpec = tween(600, delayMillis = 500)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 500))
|
||||
) {
|
||||
Button(
|
||||
onClick = onCreateSeed,
|
||||
@@ -229,12 +214,7 @@ fun WelcomeScreen(
|
||||
// Import Seed Button
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter =
|
||||
fadeIn(tween(600, delayMillis = 600)) +
|
||||
slideInVertically(
|
||||
initialOffsetY = { 100 },
|
||||
animationSpec = tween(600, delayMillis = 600)
|
||||
)
|
||||
enter = fadeIn(tween(400, delayMillis = 600))
|
||||
) {
|
||||
TextButton(
|
||||
onClick = onImportSeed,
|
||||
|
||||
Reference in New Issue
Block a user