feat: Enhance UnlockScreen with account selection dropdown and search functionality
This commit is contained in:
@@ -148,73 +148,30 @@ fun ChatsListScreen(
|
||||
onNewChat: () -> Unit,
|
||||
onLogout: () -> Unit
|
||||
) {
|
||||
// Theme transition animation state
|
||||
var isTransitioning by remember { mutableStateOf(false) }
|
||||
var transitionProgress by remember { mutableStateOf(0f) }
|
||||
var clickPosition by remember { mutableStateOf(Offset.Zero) }
|
||||
var shouldUpdateStatusBar by remember { mutableStateOf(false) }
|
||||
// Theme transition state
|
||||
var hasInitialized by remember { mutableStateOf(false) }
|
||||
var previousTheme by remember { mutableStateOf(isDarkTheme) }
|
||||
var targetTheme by remember { mutableStateOf(isDarkTheme) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
hasInitialized = true
|
||||
}
|
||||
|
||||
// Theme transition animation
|
||||
LaunchedEffect(isTransitioning) {
|
||||
if (isTransitioning) {
|
||||
shouldUpdateStatusBar = false
|
||||
val duration = 800f
|
||||
val startTime = System.currentTimeMillis()
|
||||
while (transitionProgress < 1f) {
|
||||
val elapsed = System.currentTimeMillis() - startTime
|
||||
transitionProgress = (elapsed / duration).coerceAtMost(1f)
|
||||
kotlinx.coroutines.delay(16)
|
||||
}
|
||||
shouldUpdateStatusBar = true
|
||||
kotlinx.coroutines.delay(50)
|
||||
isTransitioning = false
|
||||
transitionProgress = 0f
|
||||
shouldUpdateStatusBar = false
|
||||
previousTheme = targetTheme
|
||||
}
|
||||
}
|
||||
|
||||
val view = androidx.compose.ui.platform.LocalView.current
|
||||
|
||||
// Animate navigation bar color starting at 80% of wave animation
|
||||
LaunchedEffect(isTransitioning, transitionProgress) {
|
||||
if (isTransitioning && transitionProgress >= 0.8f && !view.isInEditMode) {
|
||||
val window = (view.context as android.app.Activity).window
|
||||
val navProgress = ((transitionProgress - 0.8f) / 0.2f).coerceIn(0f, 1f)
|
||||
|
||||
val oldColor = if (previousTheme) 0xFF1A1A1A else 0xFFFFFFFF
|
||||
val newColor = if (targetTheme) 0xFF1A1A1A else 0xFFFFFFFF
|
||||
|
||||
val r1 = (oldColor shr 16 and 0xFF)
|
||||
val g1 = (oldColor shr 8 and 0xFF)
|
||||
val b1 = (oldColor and 0xFF)
|
||||
val r2 = (newColor shr 16 and 0xFF)
|
||||
val g2 = (newColor shr 8 and 0xFF)
|
||||
val b2 = (newColor and 0xFF)
|
||||
|
||||
val r = (r1 + (r2 - r1) * navProgress).toInt()
|
||||
val g = (g1 + (g2 - g1) * navProgress).toInt()
|
||||
val b = (b1 + (b2 - b1) * navProgress).toInt()
|
||||
|
||||
window.navigationBarColor = (0xFF000000 or (r.toLong() shl 16) or (g.toLong() shl 8) or b.toLong()).toInt()
|
||||
}
|
||||
}
|
||||
|
||||
// Update status bar icons when animation finishes
|
||||
LaunchedEffect(shouldUpdateStatusBar) {
|
||||
if (shouldUpdateStatusBar && !view.isInEditMode) {
|
||||
// Update status bar and navigation bar
|
||||
LaunchedEffect(isDarkTheme, drawerState.isOpen) {
|
||||
if (!view.isInEditMode) {
|
||||
val window = (view.context as android.app.Activity).window
|
||||
val insetsController = androidx.core.view.WindowCompat.getInsetsController(window, view)
|
||||
insetsController.isAppearanceLightStatusBars = !isDarkTheme
|
||||
insetsController.isAppearanceLightNavigationBars = !isDarkTheme
|
||||
window.statusBarColor = android.graphics.Color.TRANSPARENT
|
||||
// When drawer is open, dim the navigation bar to match overlay
|
||||
window.navigationBarColor = if (drawerState.isOpen) {
|
||||
// Darker color to match scrim overlay
|
||||
if (isDarkTheme) 0xFF0D0D0D.toInt() else 0xFF999999.toInt()
|
||||
} else {
|
||||
if (isDarkTheme) 0xFF1A1A1A.toInt() else 0xFFFFFFFF.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,29 +328,12 @@ fun ChatsListScreen(
|
||||
)
|
||||
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
// Base background - shows the OLD theme color during transition
|
||||
// Simple background
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(if (isTransitioning) {
|
||||
if (previousTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF)
|
||||
} else backgroundColor)
|
||||
.background(backgroundColor)
|
||||
)
|
||||
|
||||
// Circular reveal overlay - draws the NEW theme color expanding
|
||||
if (isTransitioning) {
|
||||
Canvas(modifier = Modifier.fillMaxSize()) {
|
||||
val maxRadius = kotlin.math.hypot(size.width, size.height)
|
||||
val radius = maxRadius * transitionProgress
|
||||
|
||||
// Draw the NEW theme color expanding from click point
|
||||
drawCircle(
|
||||
color = if (targetTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF),
|
||||
radius = radius,
|
||||
center = clickPosition
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ModalNavigationDrawer(
|
||||
drawerState = drawerState,
|
||||
@@ -406,8 +346,9 @@ fun ChatsListScreen(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(if (isDarkTheme) Color(0xFF2A2A2A) else Color(0xFFF5F5F5))
|
||||
.padding(16.dp)
|
||||
.background(drawerBackgroundColor)
|
||||
.padding(top = 48.dp)
|
||||
.padding(horizontal = 16.dp, vertical = 16.dp)
|
||||
) {
|
||||
Column {
|
||||
Row(
|
||||
@@ -434,46 +375,25 @@ fun ChatsListScreen(
|
||||
|
||||
// Theme toggle
|
||||
IconButton(
|
||||
onClick = {},
|
||||
modifier = Modifier.onGloballyPositioned { coordinates ->
|
||||
// This will be handled by clickable below
|
||||
}
|
||||
onClick = onToggleTheme
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.clickable {
|
||||
if (!isTransitioning) {
|
||||
previousTheme = isDarkTheme
|
||||
targetTheme = !isDarkTheme
|
||||
// Use center of icon as click position
|
||||
val screenWidth = view.width.toFloat()
|
||||
val screenHeight = view.height.toFloat()
|
||||
clickPosition = Offset(
|
||||
screenWidth - 48.dp.value * view.resources.displayMetrics.density,
|
||||
96.dp.value * view.resources.displayMetrics.density
|
||||
)
|
||||
isTransitioning = true
|
||||
onToggleTheme()
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
if (isDarkTheme) Icons.Default.LightMode else Icons.Default.DarkMode,
|
||||
contentDescription = "Toggle theme",
|
||||
tint = textColor
|
||||
)
|
||||
}
|
||||
Icon(
|
||||
if (isDarkTheme) Icons.Default.LightMode else Icons.Default.DarkMode,
|
||||
contentDescription = "Toggle theme",
|
||||
tint = textColor
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Account name
|
||||
// Public key instead of account name
|
||||
Text(
|
||||
text = accountName,
|
||||
fontSize = 18.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = textColor
|
||||
text = accountPublicKey,
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
color = secondaryTextColor,
|
||||
maxLines = 1
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -508,6 +428,8 @@ fun ChatsListScreen(
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
// Logout button at bottom
|
||||
Divider(
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
@@ -545,6 +467,7 @@ fun ChatsListScreen(
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.navigationBarsPadding())
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user