feat: Enhance DeviceConfirmScreen with animated color transitions and improved layout

This commit is contained in:
2026-02-19 17:50:25 +05:00
parent 53d0e44ef8
commit 5cf8b2866f

View File

@@ -1,7 +1,9 @@
package com.rosetta.messenger.ui.auth package com.rosetta.messenger.ui.auth
import android.os.Build import android.os.Build
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.FastOutSlowInEasing import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.CubicBezierEasing
import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.animation.core.rememberInfiniteTransition
@@ -16,6 +18,7 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
@@ -36,7 +39,6 @@ import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
@@ -62,15 +64,36 @@ fun DeviceConfirmScreen(
isDarkTheme: Boolean, isDarkTheme: Boolean,
onExit: () -> Unit onExit: () -> Unit
) { ) {
val backgroundTop = if (isDarkTheme) Color(0xFF17181D) else Color(0xFFF4F7FC) val themeAnimSpec =
val backgroundBottom = if (isDarkTheme) Color(0xFF121316) else Color(0xFFE9EEF7) tween<Color>(durationMillis = 500, easing = CubicBezierEasing(0.4f, 0f, 0.2f, 1f))
val cardColor = if (isDarkTheme) Color(0xFF23252B) else Color.White
val cardBorderColor = if (isDarkTheme) Color(0xFF343844) else Color(0xFFDCE4F0) val backgroundColor by
val textColor = if (isDarkTheme) Color(0xFFF2F3F5) else Color(0xFF1B1C1F) animateColorAsState(
val secondaryTextColor = if (isDarkTheme) Color(0xFFB2B5BD) else Color(0xFF6F7480) targetValue = if (isDarkTheme) AuthBackground else AuthBackgroundLight,
val accentColor = if (isDarkTheme) Color(0xFF4A9FFF) else PrimaryBlue animationSpec = themeAnimSpec
val deviceCardColor = if (isDarkTheme) Color(0xFF1A1C22) else Color(0xFFF5F8FD) )
val exitButtonColor = if (isDarkTheme) Color(0xFF3D2227) else Color(0xFFFFEAED) val surfaceColor by
animateColorAsState(
targetValue = if (isDarkTheme) AuthSurface else AuthSurfaceLight,
animationSpec = themeAnimSpec
)
val borderColor by
animateColorAsState(
targetValue = if (isDarkTheme) Color(0xFF3E3E43) else Color(0xFFE3E3E8),
animationSpec = themeAnimSpec
)
val textColor by
animateColorAsState(
targetValue = if (isDarkTheme) Color.White else Color.Black,
animationSpec = themeAnimSpec
)
val secondaryTextColor by
animateColorAsState(
targetValue = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666),
animationSpec = themeAnimSpec
)
val accentColor = PrimaryBlue
val exitButtonColor = if (isDarkTheme) Color(0xFF3A2629) else Color(0xFFFFEAED)
val exitButtonTextColor = Color(0xFFFF5E61) val exitButtonTextColor = Color(0xFFFF5E61)
val onExitState by rememberUpdatedState(onExit) val onExitState by rememberUpdatedState(onExit)
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
@@ -105,147 +128,149 @@ fun DeviceConfirmScreen(
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background( .background(backgroundColor)
brush = .statusBarsPadding()
Brush.verticalGradient(
colors = listOf(backgroundTop, backgroundBottom)
)
)
.navigationBarsPadding() .navigationBarsPadding()
.padding(horizontal = 22.dp), .padding(horizontal = 22.dp),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
Surface( Column(
modifier = Modifier modifier =
.fillMaxWidth() Modifier
.widthIn(max = 400.dp), .fillMaxWidth()
color = cardColor, .widthIn(max = 420.dp),
shape = RoundedCornerShape(28.dp), horizontalAlignment = Alignment.CenterHorizontally
border = BorderStroke(1.dp, cardBorderColor)
) { ) {
Column( Spacer(modifier = Modifier.weight(0.2f))
modifier = Modifier.padding(horizontal = 22.dp, vertical = 24.dp),
horizontalAlignment = Alignment.CenterHorizontally, Box(
verticalArrangement = Arrangement.Center modifier =
Modifier
.size(102.dp)
.clip(RoundedCornerShape(24.dp))
.background(accentColor.copy(alpha = if (isDarkTheme) 0.14f else 0.12f)),
contentAlignment = Alignment.Center
) { ) {
Box( LottieAnimation(
modifier = composition = composition,
Modifier progress = { progress },
.size(118.dp) modifier = Modifier.size(82.dp)
.clip(CircleShape) )
.background(accentColor.copy(alpha = if (isDarkTheme) 0.16f else 0.1f)), }
contentAlignment = Alignment.Center
Spacer(modifier = Modifier.height(18.dp))
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
imageVector = TablerIcons.DeviceMobile,
contentDescription = null,
tint = accentColor,
modifier = Modifier.size(16.dp)
)
Spacer(modifier = Modifier.size(6.dp))
Text(
text = "NEW DEVICE REQUEST",
color = accentColor,
fontSize = 12.sp,
fontWeight = FontWeight.SemiBold
)
}
Spacer(modifier = Modifier.height(12.dp))
Text(
text = "Waiting for approval",
color = textColor,
fontSize = 30.sp,
lineHeight = 36.sp,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(10.dp))
Text(
text = "Open Rosetta on your first device and approve this login request.",
color = secondaryTextColor,
fontSize = 15.sp,
textAlign = TextAlign.Center,
lineHeight = 22.sp
)
Spacer(modifier = Modifier.height(20.dp))
Surface(
modifier = Modifier.fillMaxWidth(),
color = surfaceColor,
shape = RoundedCornerShape(14.dp),
border = BorderStroke(1.dp, borderColor)
) {
Column(
modifier = Modifier.padding(horizontal = 14.dp, vertical = 12.dp),
verticalArrangement = Arrangement.spacedBy(4.dp)
) { ) {
LottieAnimation(
composition = composition,
progress = { progress },
modifier = Modifier.size(96.dp)
)
}
Spacer(modifier = Modifier.height(16.dp))
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
imageVector = TablerIcons.DeviceMobile,
contentDescription = null,
tint = accentColor
)
Spacer(modifier = Modifier.size(6.dp))
Text( Text(
text = "NEW DEVICE REQUEST", text = "This device",
color = accentColor, color = secondaryTextColor,
fontSize = 12.sp, fontSize = 12.sp,
fontWeight = FontWeight.Bold fontWeight = FontWeight.Medium
) )
}
Spacer(modifier = Modifier.height(14.dp))
Text(
text = "Waiting for approval",
color = textColor,
fontSize = 34.sp,
lineHeight = 38.sp,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(12.dp))
Text(
text = "Open Rosetta on your first device and approve this login request.",
color = secondaryTextColor,
fontSize = 15.sp,
textAlign = TextAlign.Center,
lineHeight = 22.sp
)
Spacer(modifier = Modifier.height(18.dp))
Surface(
modifier = Modifier.fillMaxWidth(),
color = deviceCardColor,
shape = RoundedCornerShape(16.dp),
border = BorderStroke(1.dp, cardBorderColor.copy(alpha = if (isDarkTheme) 0.7f else 1f))
) {
Column(
modifier = Modifier.padding(horizontal = 14.dp, vertical = 12.dp),
horizontalAlignment = Alignment.Start
) {
Text(
text = "Device waiting for approval",
color = secondaryTextColor,
fontSize = 12.sp,
fontWeight = FontWeight.SemiBold
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = localDeviceName,
color = textColor,
fontSize = 17.sp,
fontWeight = FontWeight.SemiBold
)
}
}
Spacer(modifier = Modifier.height(16.dp))
Button(
onClick = onExitState,
modifier =
Modifier
.fillMaxWidth()
.height(46.dp),
colors = ButtonDefaults.buttonColors(
containerColor = exitButtonColor,
contentColor = exitButtonTextColor
),
border = BorderStroke(1.dp, exitButtonTextColor.copy(alpha = 0.35f)),
shape = RoundedCornerShape(14.dp)
) {
Text( Text(
text = "Exit", text = localDeviceName,
fontSize = 16.sp, color = textColor,
fontSize = 17.sp,
fontWeight = FontWeight.SemiBold fontWeight = FontWeight.SemiBold
) )
} }
Spacer(modifier = Modifier.height(14.dp))
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Text(
text = "Waiting for confirmation",
color = secondaryTextColor,
fontSize = 12.sp
)
Spacer(modifier = Modifier.size(8.dp))
WaitingDots(color = secondaryTextColor)
}
} }
Spacer(modifier = Modifier.height(14.dp))
Text(
text = "If this wasn't you, tap Exit.",
color = secondaryTextColor,
fontSize = 13.sp,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(18.dp))
Button(
onClick = onExitState,
modifier =
Modifier
.fillMaxWidth()
.height(52.dp),
colors = ButtonDefaults.buttonColors(
containerColor = exitButtonColor,
contentColor = exitButtonTextColor
),
border = BorderStroke(1.dp, exitButtonTextColor.copy(alpha = 0.35f)),
shape = RoundedCornerShape(14.dp)
) {
Text(
text = "Exit",
fontSize = 17.sp,
fontWeight = FontWeight.SemiBold
)
}
Spacer(modifier = Modifier.height(14.dp))
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Text(
text = "Waiting for confirmation",
color = secondaryTextColor,
fontSize = 12.sp
)
Spacer(modifier = Modifier.size(8.dp))
WaitingDots(color = secondaryTextColor)
}
Spacer(modifier = Modifier.weight(0.24f))
} }
} }
} }