diff --git a/app/src/main/java/com/m57/hermescontrol/ui/chat/InlineAttachment.kt b/app/src/main/java/com/m57/hermescontrol/ui/chat/InlineAttachment.kt index cba72589..c5716f4b 100644 --- a/app/src/main/java/com/m57/hermescontrol/ui/chat/InlineAttachment.kt +++ b/app/src/main/java/com/m57/hermescontrol/ui/chat/InlineAttachment.kt @@ -34,6 +34,39 @@ import androidx.compose.ui.unit.dp import com.m57.hermescontrol.R import com.m57.hermescontrol.data.model.Attachment +/** + * Renders a message's attachments, shared by user bubbles and agent messages. + * Emits directly into the caller's Column (no wrapper) so spacing is unchanged: + * 6dp before the list, 4dp after each item. Renders nothing when empty. + */ +@Composable +internal fun InlineAttachmentList( + attachments: List?, + textColor: Color, + onOpen: (Attachment) -> Unit, + onSave: (Attachment) -> Unit, + savingPath: String?, + openingPath: String?, + canSave: Boolean, + onImageClick: (ImageViewerModel) -> Unit, +) { + if (attachments.isNullOrEmpty()) return + Spacer(modifier = Modifier.height(6.dp)) + attachments.forEach { attachment -> + InlineAttachment( + attachment = attachment, + textColor = textColor, + onOpen = onOpen, + onSave = onSave, + savingPath = savingPath, + openingPath = openingPath, + canSave = canSave, + onImageClick = onImageClick, + ) + Spacer(modifier = Modifier.height(4.dp)) + } +} + /** * Renders an attachment inline inside a chat bubble. * Images are displayed as thumbnails; other files show a compact card. diff --git a/app/src/main/java/com/m57/hermescontrol/ui/chat/UserBubble.kt b/app/src/main/java/com/m57/hermescontrol/ui/chat/UserBubble.kt index 33332774..d4a73087 100644 --- a/app/src/main/java/com/m57/hermescontrol/ui/chat/UserBubble.kt +++ b/app/src/main/java/com/m57/hermescontrol/ui/chat/UserBubble.kt @@ -177,22 +177,16 @@ fun UserBubble( ) } // Render inline attachments - if (!message.attachments.isNullOrEmpty()) { - Spacer(modifier = Modifier.height(6.dp)) - message.attachments.forEach { attachment -> - InlineAttachment( - attachment = attachment, - textColor = userBubbleTextColor, - onOpen = { onOpenAttachment(it) }, - onSave = { onSaveAttachment(it) }, - savingPath = savingAttachmentPath, - openingPath = openingAttachmentPath, - canSave = canSaveAttachment, - onImageClick = onImageClick, - ) - Spacer(modifier = Modifier.height(4.dp)) - } - } + InlineAttachmentList( + attachments = message.attachments, + textColor = userBubbleTextColor, + onOpen = onOpenAttachment, + onSave = onSaveAttachment, + savingPath = savingAttachmentPath, + openingPath = openingAttachmentPath, + canSave = canSaveAttachment, + onImageClick = onImageClick, + ) if (!message.isStreaming) { FlowRow( modifier = diff --git a/app/src/main/java/com/m57/hermescontrol/ui/chat/fullbleed/FullBleedAgentMessage.kt b/app/src/main/java/com/m57/hermescontrol/ui/chat/fullbleed/FullBleedAgentMessage.kt index 52b226bb..318f3806 100644 --- a/app/src/main/java/com/m57/hermescontrol/ui/chat/fullbleed/FullBleedAgentMessage.kt +++ b/app/src/main/java/com/m57/hermescontrol/ui/chat/fullbleed/FullBleedAgentMessage.kt @@ -36,7 +36,7 @@ import com.m57.hermescontrol.R import com.m57.hermescontrol.data.model.Attachment import com.m57.hermescontrol.ui.chat.ChatMessage import com.m57.hermescontrol.ui.chat.ImageViewerModel -import com.m57.hermescontrol.ui.chat.InlineAttachment +import com.m57.hermescontrol.ui.chat.InlineAttachmentList import com.m57.hermescontrol.ui.chat.MarkdownText import com.m57.hermescontrol.ui.chat.TokenEstimator import com.m57.hermescontrol.ui.chat.components.ReasoningCard @@ -109,24 +109,18 @@ internal fun FullBleedAgentMessage( } } - // Render inline attachments (mirrors ChatBubble so agent-delivered + // Inline attachments (shared with UserBubble so agent-delivered // media — images, files — shows in full-bleed mode too). - if (!message.attachments.isNullOrEmpty()) { - Spacer(modifier = Modifier.height(6.dp)) - message.attachments.forEach { attachment -> - InlineAttachment( - attachment = attachment, - textColor = textColor, - onOpen = { onOpenAttachment(it) }, - onSave = { onSaveAttachment(it) }, - savingPath = savingAttachmentPath, - openingPath = openingAttachmentPath, - canSave = canSaveAttachment, - onImageClick = onImageClick, - ) - Spacer(modifier = Modifier.height(4.dp)) - } - } + InlineAttachmentList( + attachments = message.attachments, + textColor = textColor, + onOpen = onOpenAttachment, + onSave = onSaveAttachment, + savingPath = savingAttachmentPath, + openingPath = openingAttachmentPath, + canSave = canSaveAttachment, + onImageClick = onImageClick, + ) if (!message.isStreaming && message.content.isNotBlank()) { val showTokenStat =