feat: edit and resend user messages

Pencil icon on user messages (next to copy, before delete). Tap removes
the edited message and all messages after it from the UI + server, then
puts the text back into the input field for editing and resending.

Only shown on user messages with text content (not voice-only), and only
when not currently streaming.
This commit is contained in:
Bruno Deanoz 2026-06-23 01:30:52 +02:00
parent 44ff82a66d
commit 8f72afd714
2 changed files with 24 additions and 0 deletions

View file

@ -447,6 +447,7 @@ fun MessageRow(
onCopy: (String) -> Unit = {},
onDelete: ((String) -> Unit)? = null,
onRegenerate: ((String) -> Unit)? = null,
onEdit: ((String, String) -> Unit)? = null,
onReadAloud: ((String) -> Unit)? = null,
isPlayingTts: Boolean = false,
) {
@ -544,6 +545,13 @@ fun MessageRow(
copied = false
}
}
if (message.content.isNotBlank()) {
onEdit?.let { edit ->
MessageActionButton(KaizenIcons.Pencil, cs.onSurfaceVariant.copy(alpha = 0.50f)) {
haptics.tick(); edit(message.wireId, message.content)
}
}
}
onDelete?.let { del ->
MessageActionButton(KaizenIcons.Trash, Color(0xFFEF4444).copy(alpha = 0.70f)) {
haptics.tick(); del(message.wireId)

View file

@ -883,6 +883,22 @@ fun ChatScreen(
send(userContent)
}
} 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 ->
readAloud(content, message.id, message.wireId)
} else null,