From 44ff82a66d000e0cf5b8c22c1c529d63e293e25c Mon Sep 17 00:00:00 2001 From: Bruno Deanoz Date: Tue, 23 Jun 2026 01:28:53 +0200 Subject: [PATCH] fix: voice messages appear in wrong order after reopening chat Voice auto-send was saving messages to the server but not caching them in Room with correct sortOrder. When navigating away and back, the app loaded from Room cache (empty for voice messages) then from server, where the tree-based ordering could differ from insertion order. Now caches both user and assistant messages in Room with proper sortOrder after the server save succeeds, matching the normal send() flow. --- .../java/dev/kaizen/app/chat/ChatScreen.kt | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/dev/kaizen/app/chat/ChatScreen.kt b/app/src/main/java/dev/kaizen/app/chat/ChatScreen.kt index 142db93..7d9db95 100644 --- a/app/src/main/java/dev/kaizen/app/chat/ChatScreen.kt +++ b/app/src/main/java/dev/kaizen/app/chat/ChatScreen.kt @@ -283,9 +283,29 @@ fun ChatScreen( val cid = convIdDeferred?.await() ?: conversationId ?: return@launch if (conversationId == null) conversationId = cid val assistantMsg = messages.lastOrNull { it.id == assistantId } ?: return@launch + val finalContent = assistantMsg.content + val finalReasoning = assistantMsg.reasoning.takeIf { it.isNotBlank() } + val finalSources = assistantMsg.sources.takeIf { it.isNotEmpty() } val userSave = SaveMessage(id = userMsg.wireId, parentId = userParentId, role = "user", content = "", attachments = listOf(att)) - val assistantSave = SaveMessage(id = assistantMsg.wireId, parentId = userMsg.wireId, role = "assistant", content = assistantMsg.content, model = cfg.model, reasoning = assistantMsg.reasoning.takeIf { it.isNotBlank() }, sources = assistantMsg.sources.takeIf { it.isNotEmpty() }?.map { dev.kaizen.app.net.SearchSource(it.title, it.url, it.snippet) }) - KaizenApi.saveMessages(cfg.baseUrl, cfg.token, cid, listOf(userSave, assistantSave)) + val assistantSave = SaveMessage(id = assistantWireId, parentId = userMsg.wireId, role = "assistant", content = finalContent, model = cfg.model, reasoning = finalReasoning, sources = finalSources?.map { dev.kaizen.app.net.SearchSource(it.title, it.url, it.snippet) }) + val saved = KaizenApi.saveMessages(cfg.baseUrl, cfg.token, cid, listOf(userSave, assistantSave)) + if (saved) { + val msgCount = messages.size + chat.messageRepo.cacheMessages(cid, listOf( + dev.kaizen.app.db.MessageEntity( + id = userMsg.wireId, conversationId = cid, + role = "user", content = "", + attachments = listOf(att), sortOrder = msgCount - 2, + ), + dev.kaizen.app.db.MessageEntity( + id = assistantWireId, conversationId = cid, + role = "assistant", content = finalContent, + attachments = emptyList(), sortOrder = msgCount - 1, + reasoning = finalReasoning, + sources = finalSources?.map { dev.kaizen.app.net.SearchSource(it.title, it.url, it.snippet) } ?: emptyList(), + ), + )) + } if (convIdDeferred != null) { chat.conversationRepo.insertOptimistic(cid, "(Voice)") val title = KaizenApi.generateTitle(cfg.baseUrl, cfg.token, cid)