diff --git a/app/src/main/java/dev/kaizen/app/chat/ChatComponents.kt b/app/src/main/java/dev/kaizen/app/chat/ChatComponents.kt index 9101046..465647b 100644 --- a/app/src/main/java/dev/kaizen/app/chat/ChatComponents.kt +++ b/app/src/main/java/dev/kaizen/app/chat/ChatComponents.kt @@ -89,6 +89,7 @@ import androidx.compose.material.icons.rounded.VideoFile import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.material.icons.rounded.Bolt +import androidx.compose.material.icons.rounded.Mic import androidx.compose.material.icons.rounded.ExpandMore import androidx.compose.material.icons.rounded.Psychology import androidx.compose.material.icons.rounded.Tune @@ -463,10 +464,13 @@ fun ChatInput( val cs = MaterialTheme.colorScheme val isDark = isSystemInDarkTheme() + val hasContent = value.isNotBlank() || pendingFiles.any { it.uploaded != null } + val canSend = enabled && hasContent && pendingFiles.none { it.uploading } + GlassSurface( modifier = modifier .fillMaxWidth() - .padding(horizontal = 12.dp), + .padding(horizontal = 8.dp), shape = KaizenShapes.xl, tintAlpha = GlassTiers.input(isDark), shadowStack = KaizenShadows.level2, @@ -475,42 +479,38 @@ fun ChatInput( Column { if (pendingFiles.isNotEmpty()) { Row( - Modifier.fillMaxWidth().horizontalScroll(rememberScrollState()).padding(start = 12.dp, end = 12.dp, top = 8.dp), + Modifier.fillMaxWidth().horizontalScroll(rememberScrollState()).padding(start = 14.dp, end = 14.dp, top = 10.dp), horizontalArrangement = Arrangement.spacedBy(6.dp), ) { pendingFiles.forEach { pf -> PendingFileChip(pf, onRemove = { onRemoveFile(pf.id) }) } } } - Row(Modifier.padding(horizontal = 8.dp, vertical = 8.dp), verticalAlignment = Alignment.CenterVertically) { - Box(Modifier.size(40.dp).clip(KaizenShapes.circle).clickable(onClick = onAddClick), contentAlignment = Alignment.Center) { + Row(Modifier.padding(start = 6.dp, end = 8.dp, top = 10.dp, bottom = 10.dp), verticalAlignment = Alignment.Bottom) { + Box(Modifier.size(42.dp).clip(KaizenShapes.circle).clickable(onClick = onAddClick), contentAlignment = Alignment.Center) { Icon(Icons.Rounded.Add, stringResource(R.string.chat_attachment), tint = cs.onSurfaceVariant, modifier = Modifier.size(22.dp)) } - Box(Modifier.weight(1f).heightIn(min = 36.dp).padding(horizontal = 4.dp), contentAlignment = Alignment.CenterStart) { - if (value.isEmpty()) Text(stringResource(R.string.chat_input_placeholder), color = cs.onSurfaceVariant, fontSize = 16.sp) + Box(Modifier.weight(1f).heightIn(min = 42.dp).padding(horizontal = 6.dp), contentAlignment = Alignment.CenterStart) { + if (value.isEmpty()) Text(stringResource(R.string.chat_input_placeholder), color = cs.onSurfaceVariant.copy(alpha = 0.6f), fontSize = 15.sp) val accent = LocalKaizenAccent.current BasicTextField( value = value, onValueChange = onValueChange, - textStyle = TextStyle(color = cs.onBackground, fontSize = 16.sp, lineHeight = 22.sp), + textStyle = TextStyle(color = cs.onBackground, fontSize = 16.sp, lineHeight = 24.sp), cursorBrush = SolidColor(accent.primary), maxLines = 6, modifier = Modifier.fillMaxWidth(), ) } - GhostIconButton(Icons.Rounded.Call, stringResource(R.string.chat_call)) Spacer(Modifier.width(4.dp)) - val canSend = enabled && (value.isNotBlank() || pendingFiles.any { it.uploaded != null }) && pendingFiles.none { it.uploading } - SendButton(enabled = canSend, onClick = onSend) + if (hasContent) { + SendButton(enabled = canSend, onClick = onSend) + } else { + Box(Modifier.size(44.dp).clip(KaizenShapes.circle), contentAlignment = Alignment.Center) { + Icon(Icons.Rounded.Mic, stringResource(R.string.chat_call), tint = cs.onSurfaceVariant, modifier = Modifier.size(22.dp)) + } + } } } } } -@Composable -private fun GhostIconButton(icon: ImageVector, contentDescription: String) { - val cs = MaterialTheme.colorScheme - Box(Modifier.size(40.dp).clip(KaizenShapes.circle), contentAlignment = Alignment.Center) { - Icon(icon, contentDescription, tint = cs.onSurfaceVariant, modifier = Modifier.size(22.dp)) - } -} - @Composable private fun PendingFileChip(pf: PendingFile, onRemove: () -> Unit) { val cs = MaterialTheme.colorScheme