diff --git a/app/src/main/java/dev/kaizen/app/chat/StreamBlocks.kt b/app/src/main/java/dev/kaizen/app/chat/StreamBlocks.kt index d186d59..9789dfd 100644 --- a/app/src/main/java/dev/kaizen/app/chat/StreamBlocks.kt +++ b/app/src/main/java/dev/kaizen/app/chat/StreamBlocks.kt @@ -28,6 +28,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow @@ -49,44 +50,51 @@ fun ReasoningBlock(reasoning: String, streaming: Boolean = false) { val accent = LocalKaizenAccent.current var expanded by remember { mutableStateOf(streaming) } - val bg = if (isDark) Color.White.copy(alpha = 0.05f) else Color.Black.copy(alpha = 0.03f) - val borderColor = if (isDark) Color.White.copy(alpha = 0.08f) else Color.Black.copy(alpha = 0.06f) + val bg = accent.primary.copy(alpha = if (isDark) 0.06f else 0.04f) + val borderBrush = remember(isDark, accent) { + Brush.verticalGradient( + listOf( + accent.primary.copy(alpha = if (isDark) 0.20f else 0.15f), + accent.primary.copy(alpha = if (isDark) 0.05f else 0.03f), + ) + ) + } Column( Modifier .fillMaxWidth() - .clip(KaizenShapes.sm) + .clip(KaizenShapes.md) .background(bg) - .border(1.dp, borderColor, KaizenShapes.sm) + .border(0.8.dp, borderBrush, KaizenShapes.md) ) { Row( Modifier .fillMaxWidth() .clickable { expanded = !expanded } - .padding(horizontal = 12.dp, vertical = 8.dp), + .padding(horizontal = 14.dp, vertical = 10.dp), verticalAlignment = Alignment.CenterVertically, ) { - Icon(KaizenIcons.Brain, null, tint = accent.primary, modifier = Modifier.size(16.dp)) - Spacer(Modifier.width(8.dp)) + Icon(KaizenIcons.Brain, null, tint = accent.primary.copy(alpha = 0.75f), modifier = Modifier.size(17.dp)) + Spacer(Modifier.width(9.dp)) Text( stringResource(R.string.stream_reasoning), - color = cs.onSurfaceVariant, + color = cs.onSurfaceVariant.copy(alpha = 0.75f), fontSize = 13.sp, fontWeight = FontWeight.Medium, modifier = Modifier.weight(1f), ) Icon( if (expanded) KaizenIcons.ChevronUp else KaizenIcons.ChevronDown, - null, tint = cs.onSurfaceVariant, modifier = Modifier.size(16.dp), + null, tint = cs.onSurfaceVariant.copy(alpha = 0.40f), modifier = Modifier.size(15.dp), ) } AnimatedVisibility(expanded, enter = expandVertically(), exit = shrinkVertically()) { Text( reasoning, - color = cs.onSurfaceVariant.copy(alpha = 0.8f), + color = cs.onSurfaceVariant.copy(alpha = 0.70f), fontSize = 13.sp, - lineHeight = 18.sp, - modifier = Modifier.padding(start = 12.dp, end = 12.dp, bottom = 10.dp), + lineHeight = 20.sp, + modifier = Modifier.padding(start = 14.dp, end = 14.dp, bottom = 12.dp), ) } } @@ -175,18 +183,18 @@ fun SourcesBlock(sources: List, query: String = "") { .padding(vertical = 4.dp), verticalAlignment = Alignment.CenterVertically, ) { - Icon(KaizenIcons.Globe, null, tint = cs.onSurfaceVariant.copy(alpha = 0.6f), modifier = Modifier.size(13.dp)) + Icon(KaizenIcons.Globe, null, tint = cs.onSurfaceVariant.copy(alpha = 0.55f), modifier = Modifier.size(14.dp)) Spacer(Modifier.width(6.dp)) Text( stringResource(R.string.stream_sources) + " (${sources.size})", - color = cs.onSurfaceVariant.copy(alpha = 0.6f), + color = cs.onSurfaceVariant.copy(alpha = 0.55f), fontSize = 12.sp, fontWeight = FontWeight.Medium, ) Spacer(Modifier.width(4.dp)) Icon( if (expanded) KaizenIcons.ChevronUp else KaizenIcons.ChevronDown, - null, tint = cs.onSurfaceVariant.copy(alpha = 0.4f), modifier = Modifier.size(12.dp), + null, tint = cs.onSurfaceVariant.copy(alpha = 0.35f), modifier = Modifier.size(13.dp), ) } AnimatedVisibility(expanded, enter = expandVertically(), exit = shrinkVertically()) { @@ -208,7 +216,14 @@ fun SourcesBlock(sources: List, query: String = "") { private fun SourceCard(source: SearchSource, isDark: Boolean, accent: dev.kaizen.app.ui.theme.themes.KaizenAccentScheme, onClick: () -> Unit) { val cs = MaterialTheme.colorScheme val bg = if (isDark) Color.White.copy(alpha = 0.05f) else Color.Black.copy(alpha = 0.03f) - val borderColor = if (isDark) Color.White.copy(alpha = 0.06f) else Color.Black.copy(alpha = 0.05f) + val borderBrush = remember(isDark) { + Brush.verticalGradient( + listOf( + if (isDark) Color.White.copy(alpha = 0.10f) else Color.Black.copy(alpha = 0.06f), + if (isDark) Color.White.copy(alpha = 0.03f) else Color.Black.copy(alpha = 0.02f), + ) + ) + } val domain = remember(source.url) { try { @@ -219,11 +234,11 @@ private fun SourceCard(source: SearchSource, isDark: Boolean, accent: dev.kaizen Column( Modifier .fillMaxWidth() - .clip(KaizenShapes.sm) + .clip(KaizenShapes.md) .background(bg) - .border(1.dp, borderColor, KaizenShapes.sm) + .border(0.8.dp, borderBrush, KaizenShapes.md) .clickable(onClick = onClick) - .padding(horizontal = 12.dp, vertical = 10.dp), + .padding(horizontal = 14.dp, vertical = 10.dp), ) { Text( source.title.ifEmpty { domain }, @@ -235,8 +250,8 @@ private fun SourceCard(source: SearchSource, isDark: Boolean, accent: dev.kaizen ) Spacer(Modifier.height(2.dp)) Text( - source.url, - color = accent.primary.copy(alpha = 0.7f), + domain, + color = accent.primary.copy(alpha = 0.65f), fontSize = 11.sp, maxLines = 1, overflow = TextOverflow.Ellipsis, @@ -245,7 +260,7 @@ private fun SourceCard(source: SearchSource, isDark: Boolean, accent: dev.kaizen Spacer(Modifier.height(3.dp)) Text( source.snippet, - color = cs.onSurfaceVariant.copy(alpha = 0.5f), + color = cs.onSurfaceVariant.copy(alpha = 0.50f), fontSize = 11.sp, maxLines = 2, overflow = TextOverflow.Ellipsis,