feat: Update navigation bar color logic to match drawer background when open
This commit is contained in:
@@ -278,69 +278,70 @@ fun UnlockScreen(
|
|||||||
// Dropdown list with animation
|
// Dropdown list with animation
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = isDropdownExpanded,
|
visible = isDropdownExpanded,
|
||||||
enter = fadeIn(tween(200)) + expandVertically(
|
enter = fadeIn(tween(150)) + expandVertically(
|
||||||
expandFrom = Alignment.Top,
|
expandFrom = Alignment.Top,
|
||||||
animationSpec = spring(
|
animationSpec = tween(200, easing = FastOutSlowInEasing)
|
||||||
dampingRatio = Spring.DampingRatioMediumBouncy,
|
|
||||||
stiffness = Spring.StiffnessMediumLow
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
exit = fadeOut(tween(150)) + shrinkVertically(
|
exit = fadeOut(tween(100)) + shrinkVertically(
|
||||||
shrinkTowards = Alignment.Top,
|
shrinkTowards = Alignment.Top,
|
||||||
animationSpec = tween(200)
|
animationSpec = tween(150)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(top = 8.dp)
|
.padding(top = 8.dp)
|
||||||
.heightIn(max = 300.dp),
|
.heightIn(max = if (accounts.size > 5) 350.dp else ((accounts.size * 64 + 70).dp)),
|
||||||
colors = CardDefaults.cardColors(containerColor = cardBackground),
|
colors = CardDefaults.cardColors(containerColor = cardBackground),
|
||||||
shape = RoundedCornerShape(16.dp)
|
shape = RoundedCornerShape(16.dp)
|
||||||
) {
|
) {
|
||||||
Column {
|
Column {
|
||||||
// Search field
|
// Search field - only show if more than 3 accounts
|
||||||
OutlinedTextField(
|
if (accounts.size > 3) {
|
||||||
value = searchQuery,
|
OutlinedTextField(
|
||||||
onValueChange = { searchQuery = it },
|
value = searchQuery,
|
||||||
placeholder = {
|
onValueChange = { searchQuery = it },
|
||||||
Text(
|
placeholder = {
|
||||||
"Search accounts...",
|
Text(
|
||||||
color = secondaryTextColor.copy(alpha = 0.6f)
|
"Search accounts...",
|
||||||
)
|
color = secondaryTextColor.copy(alpha = 0.6f)
|
||||||
},
|
)
|
||||||
leadingIcon = {
|
},
|
||||||
Icon(
|
leadingIcon = {
|
||||||
Icons.Default.Search,
|
Icon(
|
||||||
contentDescription = null,
|
Icons.Default.Search,
|
||||||
tint = secondaryTextColor
|
contentDescription = null,
|
||||||
)
|
tint = secondaryTextColor
|
||||||
},
|
)
|
||||||
colors = OutlinedTextFieldDefaults.colors(
|
},
|
||||||
focusedBorderColor = PrimaryBlue,
|
colors = OutlinedTextFieldDefaults.colors(
|
||||||
unfocusedBorderColor = Color.Transparent,
|
focusedBorderColor = PrimaryBlue,
|
||||||
focusedContainerColor = Color.Transparent,
|
unfocusedBorderColor = Color.Transparent,
|
||||||
unfocusedContainerColor = Color.Transparent,
|
focusedContainerColor = Color.Transparent,
|
||||||
focusedTextColor = textColor,
|
unfocusedContainerColor = Color.Transparent,
|
||||||
unfocusedTextColor = textColor,
|
focusedTextColor = textColor,
|
||||||
cursorColor = PrimaryBlue
|
unfocusedTextColor = textColor,
|
||||||
),
|
cursorColor = PrimaryBlue
|
||||||
singleLine = true,
|
),
|
||||||
modifier = Modifier
|
singleLine = true,
|
||||||
.fillMaxWidth()
|
modifier = Modifier
|
||||||
.padding(horizontal = 12.dp, vertical = 8.dp)
|
.fillMaxWidth()
|
||||||
.focusRequester(searchFocusRequester),
|
.padding(horizontal = 12.dp, vertical = 8.dp)
|
||||||
shape = RoundedCornerShape(12.dp)
|
.focusRequester(searchFocusRequester),
|
||||||
)
|
shape = RoundedCornerShape(12.dp)
|
||||||
|
)
|
||||||
|
|
||||||
Divider(
|
Divider(
|
||||||
color = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE0E0E0),
|
color = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE0E0E0),
|
||||||
thickness = 0.5.dp
|
thickness = 0.5.dp
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Account list
|
// Account list
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = if (accounts.size <= 3) 8.dp else 0.dp)
|
||||||
) {
|
) {
|
||||||
items(filteredAccounts, key = { it.publicKey }) { account ->
|
items(filteredAccounts, key = { it.publicKey }) { account ->
|
||||||
val isSelected = account.publicKey == selectedAccount?.publicKey
|
val isSelected = account.publicKey == selectedAccount?.publicKey
|
||||||
|
|||||||
@@ -159,45 +159,27 @@ fun ChatsListScreen(
|
|||||||
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
|
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
// Update status bar and navigation bar
|
// Update status bar and hide navigation bar completely
|
||||||
LaunchedEffect(isDarkTheme, drawerState.isOpen) {
|
LaunchedEffect(isDarkTheme, drawerState.isOpen) {
|
||||||
if (!view.isInEditMode) {
|
if (!view.isInEditMode) {
|
||||||
val window = (view.context as android.app.Activity).window
|
val window = (view.context as android.app.Activity).window
|
||||||
val insetsController = androidx.core.view.WindowCompat.getInsetsController(window, view)
|
val insetsController = androidx.core.view.WindowCompat.getInsetsController(window, view)
|
||||||
|
|
||||||
|
// Status bar
|
||||||
insetsController.isAppearanceLightStatusBars = !isDarkTheme
|
insetsController.isAppearanceLightStatusBars = !isDarkTheme
|
||||||
insetsController.isAppearanceLightNavigationBars = !isDarkTheme
|
|
||||||
window.statusBarColor = android.graphics.Color.TRANSPARENT
|
window.statusBarColor = android.graphics.Color.TRANSPARENT
|
||||||
// When drawer is open, dim the navigation bar to match overlay
|
|
||||||
window.navigationBarColor = if (drawerState.isOpen) {
|
// Hide navigation bar completely
|
||||||
// Darker color to match scrim overlay
|
insetsController.hide(androidx.core.view.WindowInsetsCompat.Type.navigationBars())
|
||||||
if (isDarkTheme) 0xFF0D0D0D.toInt() else 0xFF999999.toInt()
|
insetsController.systemBarsBehavior = androidx.core.view.WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||||
} else {
|
|
||||||
if (isDarkTheme) 0xFF1A1A1A.toInt() else 0xFFFFFFFF.toInt()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val backgroundColor by animateColorAsState(
|
// Colors - instant change, no animation (to keep sidebar and content in sync)
|
||||||
targetValue = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF),
|
val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF)
|
||||||
animationSpec = if (!hasInitialized) snap() else tween(800, easing = FastOutSlowInEasing),
|
|
||||||
label = "backgroundColor"
|
|
||||||
)
|
|
||||||
val drawerBackgroundColor = if (isDarkTheme) Color(0xFF212121) else Color(0xFFFFFFFF)
|
val drawerBackgroundColor = if (isDarkTheme) Color(0xFF212121) else Color(0xFFFFFFFF)
|
||||||
val textColor by animateColorAsState(
|
val textColor = if (isDarkTheme) Color.White else Color.Black
|
||||||
targetValue = if (isDarkTheme) Color.White else Color.Black,
|
val secondaryTextColor = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666)
|
||||||
animationSpec = if (!hasInitialized) snap() else tween(800, easing = FastOutSlowInEasing),
|
|
||||||
label = "textColor"
|
|
||||||
)
|
|
||||||
val secondaryTextColor by animateColorAsState(
|
|
||||||
targetValue = if (isDarkTheme) Color(0xFF8E8E93) else Color(0xFF666666),
|
|
||||||
animationSpec = if (!hasInitialized) snap() else tween(800, easing = FastOutSlowInEasing),
|
|
||||||
label = "secondaryTextColor"
|
|
||||||
)
|
|
||||||
val dividerColor by animateColorAsState(
|
|
||||||
targetValue = if (isDarkTheme) Color(0xFF3A3A3A) else Color(0xFFE8E8E8),
|
|
||||||
animationSpec = if (!hasInitialized) snap() else tween(800, easing = FastOutSlowInEasing),
|
|
||||||
label = "dividerColor"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Protocol connection state
|
// Protocol connection state
|
||||||
val protocolState by ProtocolManager.state.collectAsState()
|
val protocolState by ProtocolManager.state.collectAsState()
|
||||||
@@ -684,11 +666,13 @@ fun ChatsListScreen(
|
|||||||
|
|
||||||
if (searchButtonScale > 0.01f) {
|
if (searchButtonScale > 0.01f) {
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = { isSearchExpanded = true },
|
onClick = { /* TODO: Search not implemented yet */ },
|
||||||
|
enabled = false,
|
||||||
modifier = Modifier.graphicsLayer {
|
modifier = Modifier.graphicsLayer {
|
||||||
scaleX = searchButtonScale
|
scaleX = searchButtonScale
|
||||||
scaleY = searchButtonScale
|
scaleY = searchButtonScale
|
||||||
rotationZ = searchButtonRotation
|
rotationZ = searchButtonRotation
|
||||||
|
alpha = 0.5f
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
@@ -708,7 +692,7 @@ fun ChatsListScreen(
|
|||||||
},
|
},
|
||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = visible,
|
visible = false, // Hidden for now
|
||||||
enter = fadeIn(tween(500, delayMillis = 300)) + scaleIn(
|
enter = fadeIn(tween(500, delayMillis = 300)) + scaleIn(
|
||||||
initialScale = 0.5f,
|
initialScale = 0.5f,
|
||||||
animationSpec = tween(500, delayMillis = 300)
|
animationSpec = tween(500, delayMillis = 300)
|
||||||
@@ -735,9 +719,9 @@ fun ChatsListScreen(
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(paddingValues)
|
.padding(paddingValues)
|
||||||
) {
|
) {
|
||||||
// Console button
|
// Console button - hidden for now
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = visible,
|
visible = false,
|
||||||
enter = fadeIn(tween(500, delayMillis = 400)) + slideInHorizontally(
|
enter = fadeIn(tween(500, delayMillis = 400)) + slideInHorizontally(
|
||||||
initialOffsetX = { -it },
|
initialOffsetX = { -it },
|
||||||
animationSpec = tween(500, delayMillis = 400)
|
animationSpec = tween(500, delayMillis = 400)
|
||||||
|
|||||||
Reference in New Issue
Block a user