Compare commits

..

No commits in common. "b2df7e9330032b147857917f65b102ecf99a8619" and "44ff82a66d000e0cf5b8c22c1c529d63e293e25c" have entirely different histories.

3 changed files with 10 additions and 38 deletions

View file

@ -447,7 +447,6 @@ fun MessageRow(
onCopy: (String) -> Unit = {}, onCopy: (String) -> Unit = {},
onDelete: ((String) -> Unit)? = null, onDelete: ((String) -> Unit)? = null,
onRegenerate: ((String) -> Unit)? = null, onRegenerate: ((String) -> Unit)? = null,
onEdit: ((String, String) -> Unit)? = null,
onReadAloud: ((String) -> Unit)? = null, onReadAloud: ((String) -> Unit)? = null,
isPlayingTts: Boolean = false, isPlayingTts: Boolean = false,
) { ) {
@ -531,11 +530,11 @@ fun MessageRow(
if (!message.streaming) { if (!message.streaming) {
Row( Row(
Modifier.padding(top = 6.dp, end = 4.dp), Modifier.padding(top = 6.dp, end = 4.dp),
horizontalArrangement = Arrangement.spacedBy(2.dp), horizontalArrangement = Arrangement.spacedBy(4.dp),
) { ) {
MessageActionButton( MessageActionButton(
icon = if (copied) KaizenIcons.Check else KaizenIcons.ClipboardCopy, icon = if (copied) KaizenIcons.Check else KaizenIcons.Copy,
tint = if (copied) Color(0xFF10B981) else cs.onSurfaceVariant.copy(alpha = 0.55f), tint = if (copied) Color(0xFF10B981) else cs.onSurfaceVariant.copy(alpha = 0.50f),
) { ) {
haptics.tick() haptics.tick()
copied = true copied = true
@ -545,13 +544,6 @@ fun MessageRow(
copied = false copied = false
} }
} }
if (message.content.isNotBlank()) {
onEdit?.let { edit ->
MessageActionButton(KaizenIcons.SquarePen, cs.onSurfaceVariant.copy(alpha = 0.55f)) {
haptics.tick(); edit(message.wireId, message.content)
}
}
}
onDelete?.let { del -> onDelete?.let { del ->
MessageActionButton(KaizenIcons.Trash, Color(0xFFEF4444).copy(alpha = 0.70f)) { MessageActionButton(KaizenIcons.Trash, Color(0xFFEF4444).copy(alpha = 0.70f)) {
haptics.tick(); del(message.wireId) haptics.tick(); del(message.wireId)
@ -591,11 +583,11 @@ fun MessageRow(
if (!message.streaming && !message.thinking && message.content.isNotBlank()) { if (!message.streaming && !message.thinking && message.content.isNotBlank()) {
Row( Row(
Modifier.padding(start = 38.dp, top = 6.dp), Modifier.padding(start = 38.dp, top = 6.dp),
horizontalArrangement = Arrangement.spacedBy(2.dp), horizontalArrangement = Arrangement.spacedBy(4.dp),
) { ) {
MessageActionButton( MessageActionButton(
icon = if (copied) KaizenIcons.Check else KaizenIcons.ClipboardCopy, icon = if (copied) KaizenIcons.Check else KaizenIcons.Copy,
tint = if (copied) Color(0xFF10B981) else cs.onSurfaceVariant.copy(alpha = 0.55f), tint = if (copied) Color(0xFF10B981) else cs.onSurfaceVariant.copy(alpha = 0.50f),
) { ) {
haptics.tick() haptics.tick()
copied = true copied = true
@ -608,13 +600,13 @@ fun MessageRow(
onReadAloud?.let { readAloud -> onReadAloud?.let { readAloud ->
MessageActionButton( MessageActionButton(
icon = KaizenIcons.Volume2, icon = KaizenIcons.Volume2,
tint = if (isPlayingTts) accent.primary else cs.onSurfaceVariant.copy(alpha = 0.55f), tint = if (isPlayingTts) accent.primary else cs.onSurfaceVariant.copy(alpha = 0.50f),
) { ) {
haptics.tick(); readAloud(message.content) haptics.tick(); readAloud(message.content)
} }
} }
onRegenerate?.let { regen -> onRegenerate?.let { regen ->
MessageActionButton(KaizenIcons.RotateCcw, cs.onSurfaceVariant.copy(alpha = 0.55f)) { MessageActionButton(KaizenIcons.RefreshCw, cs.onSurfaceVariant.copy(alpha = 0.50f)) {
haptics.tick(); regen(message.wireId) haptics.tick(); regen(message.wireId)
} }
} }
@ -680,12 +672,12 @@ private fun VoiceWaveform(amplitude: Float) {
private fun MessageActionButton(icon: ImageVector, tint: Color, onClick: () -> Unit) { private fun MessageActionButton(icon: ImageVector, tint: Color, onClick: () -> Unit) {
Box( Box(
Modifier Modifier
.size(36.dp) .size(32.dp)
.clip(KaizenShapes.circle) .clip(KaizenShapes.circle)
.clickable(onClick = onClick), .clickable(onClick = onClick),
contentAlignment = Alignment.Center, contentAlignment = Alignment.Center,
) { ) {
Icon(icon, null, tint = tint, modifier = Modifier.size(20.dp)) Icon(icon, null, tint = tint, modifier = Modifier.size(18.dp))
} }
} }

View file

@ -883,22 +883,6 @@ fun ChatScreen(
send(userContent) send(userContent)
} }
} else null, } else null,
onEdit = if (message.role == Role.User && !isStreaming) { wireId, content ->
val idx = messages.indexOfFirst { it.wireId == wireId }
if (idx >= 0) {
val cfg = session.config ?: return@MessageRow
val toRemove = messages.subList(idx, messages.size).map { it.wireId }
messages.removeAll { it.wireId in toRemove }
if (conversationId != null) {
scope.launch {
toRemove.forEach { id ->
KaizenApi.deleteMessage(cfg.baseUrl, cfg.token, conversationId!!, id)
}
}
}
input = content
}
} else null,
onReadAloud = if (message.role == Role.Assistant && !message.streaming && message.content.isNotBlank()) { content -> onReadAloud = if (message.role == Role.Assistant && !message.streaming && message.content.isNotBlank()) { content ->
readAloud(content, message.id, message.wireId) readAloud(content, message.id, message.wireId)
} else null, } else null,

View file

@ -49,17 +49,13 @@ object KaizenIcons {
// ── Conversation management ───────────────────────────────────────────── // ── Conversation management ─────────────────────────────────────────────
val Check: ImageVector get() = Lucide.Check val Check: ImageVector get() = Lucide.Check
val ClipboardCopy: ImageVector get() = Lucide.ClipboardCopy
val Copy: ImageVector get() = Lucide.Copy val Copy: ImageVector get() = Lucide.Copy
val Lock: ImageVector get() = Lucide.Lock val Lock: ImageVector get() = Lucide.Lock
val LockOpen: ImageVector get() = Lucide.LockOpen val LockOpen: ImageVector get() = Lucide.LockOpen
val Pencil: ImageVector get() = Lucide.Pencil val Pencil: ImageVector get() = Lucide.Pencil
val PenLine: ImageVector get() = Lucide.PenLine
val Pin: ImageVector get() = Lucide.Pin val Pin: ImageVector get() = Lucide.Pin
val PinOff: ImageVector get() = Lucide.PinOff val PinOff: ImageVector get() = Lucide.PinOff
val RefreshCw: ImageVector get() = Lucide.RefreshCw val RefreshCw: ImageVector get() = Lucide.RefreshCw
val RotateCcw: ImageVector get() = Lucide.RotateCcw
val SquarePen: ImageVector get() = Lucide.SquarePen
val Star: ImageVector get() = Lucide.Star val Star: ImageVector get() = Lucide.Star
val StarOff: ImageVector get() = Lucide.StarOff val StarOff: ImageVector get() = Lucide.StarOff
val Trash: ImageVector get() = Lucide.Trash2 val Trash: ImageVector get() = Lucide.Trash2