redesign top bar — unified glass pill for sidebar + model

Merge the separate hamburger circle and ModelPill into one cohesive
GlassSurface pill. Menu icon (17dp, muted) sits left, subtle 3dp dot
divider, then model name (13sp Medium, 180dp max with ellipsis).
No more chunky ExpandMore chevron. Matches the TokenBadge's glass
language on the right.
This commit is contained in:
Bruno Deanoz 2026-06-22 13:54:08 +02:00
parent e62c525386
commit 1929073ad5

View file

@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.ime
@ -694,33 +695,61 @@ fun ChatScreen(
.statusBarsPadding()
) {
Row(
modifier = Modifier.padding(start = 16.dp, top = 10.dp, end = 16.dp, bottom = 20.dp),
modifier = Modifier.padding(start = 14.dp, top = 10.dp, end = 14.dp, bottom = 20.dp),
verticalAlignment = Alignment.CenterVertically,
) {
val displayModel = chatModel ?: session.config?.model ?: ""
// Unified top bar: sidebar trigger + model name in one glass pill
GlassSurface(
shape = KaizenShapes.circle,
shape = KaizenShapes.pill,
tintAlpha = GlassTiers.pill(isSystemInDarkTheme()),
shadowStack = KaizenShadows.level2,
cornerRadius = 22.dp,
modifier = Modifier
.size(44.dp)
.clickable { haptics.tick(); scope.launch { drawerState.open() } },
shadowStack = KaizenShadows.level1,
cornerRadius = 20.dp,
) {
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
Icon(
imageVector = Icons.Rounded.Menu,
contentDescription = context.getString(R.string.chat_open_menu),
tint = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.size(20.dp)
Row(
Modifier.heightIn(min = 38.dp),
verticalAlignment = Alignment.CenterVertically,
) {
// Sidebar trigger area
Box(
Modifier
.size(38.dp)
.clip(KaizenShapes.circle)
.clickable { haptics.tick(); scope.launch { drawerState.open() } },
contentAlignment = Alignment.Center,
) {
Icon(
imageVector = Icons.Rounded.Menu,
contentDescription = context.getString(R.string.chat_open_menu),
tint = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.size(17.dp),
)
}
// Divider dot
Box(
Modifier
.size(3.dp)
.background(MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.20f), KaizenShapes.circle)
)
// Model name — tap opens picker
Box(
Modifier
.clip(KaizenShapes.pill)
.clickable { haptics.tick(); showModelSheet = true }
.padding(start = 10.dp, end = 12.dp, top = 8.dp, bottom = 8.dp),
) {
Text(
modelDisplayName(displayModel, models),
color = MaterialTheme.colorScheme.onBackground,
fontSize = 13.sp,
fontWeight = FontWeight.Medium,
maxLines = 1,
modifier = Modifier.widthIn(max = 180.dp),
overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis,
)
}
}
}
Spacer(Modifier.width(8.dp))
val displayModel = chatModel ?: session.config?.model ?: ""
ModelPill(
label = modelDisplayName(displayModel, models),
onClick = { haptics.tick(); showModelSheet = true },
)
Spacer(Modifier.weight(1f))
val ctxLen = models.find { it.id == displayModel }?.context_length ?: 1_000_000
TokenBadge(used = usedTokens, contextLength = ctxLen)