From be80e0eba8430bf50aa74debe66dd51592665b63 Mon Sep 17 00:00:00 2001 From: k1ngsterr1 Date: Wed, 4 Feb 2026 00:10:44 +0500 Subject: [PATCH] fix: add localUri support for image attachments and optimize optimistic message handling --- .../messenger/ui/chats/ChatViewModel.kt | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatViewModel.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatViewModel.kt index 9dfa532..1617a74 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatViewModel.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatViewModel.kt @@ -911,7 +911,8 @@ val newList = messages + optimisticMessages type = attachmentType, preview = attachment.optString("preview", ""), width = attachment.optInt("width", 0), - height = attachment.optInt("height", 0) + height = attachment.optInt("height", 0), + localUri = attachment.optString("localUri", "") // 🔥 Поддержка localUri из БД ) ) } @@ -1487,6 +1488,7 @@ val newList = messages + optimisticMessages val messageId = UUID.randomUUID().toString().replace("-", "").take(32) val timestamp = System.currentTimeMillis() val text = caption.trim() + val attachmentId = "img_$timestamp" // 1. 🚀 МГНОВЕННО показываем optimistic сообщение с localUri // Используем URI напрямую для отображения (без конвертации в base64) @@ -1498,7 +1500,7 @@ val newList = messages + optimisticMessages status = MessageStatus.SENDING, attachments = listOf( MessageAttachment( - id = "img_$timestamp", + id = attachmentId, blob = "", // Пока пустой, обновим после конвертации type = AttachmentType.IMAGE, preview = "", // Пока пустой, обновим после генерации @@ -1511,7 +1513,40 @@ val newList = messages + optimisticMessages addMessageSafely(optimisticMessage) _inputText.value = "" - // 2. 🔄 В ФОНЕ: конвертируем, генерируем blurhash и отправляем + // 2. 💾 СРАЗУ сохраняем в БД со статусом SENDING (delivered = 0) + // Чтобы при выходе из диалога сообщение не пропадало + viewModelScope.launch(Dispatchers.IO) { + try { + // Сохраняем с localUri в attachments для восстановления при возврате в чат + val attachmentsJson = JSONArray().apply { + put(JSONObject().apply { + put("id", attachmentId) + put("type", AttachmentType.IMAGE.value) + put("preview", "") + put("blob", "") + put("width", 0) + put("height", 0) + put("localUri", imageUri.toString()) // 🔥 Сохраняем localUri + }) + }.toString() + + // Сохраняем optimistic сообщение в БД + saveMessageToDatabase( + messageId = messageId, + text = text, + encryptedContent = "", // Пустой пока не зашифровали + encryptedKey = "", + timestamp = timestamp, + isFromMe = true, + delivered = 0, // SENDING + attachmentsJson = attachmentsJson + ) + } catch (e: Exception) { + // Игнорируем ошибку - главное что в UI показали + } + } + + // 3. 🔄 В ФОНЕ: конвертируем, генерируем blurhash и отправляем viewModelScope.launch(Dispatchers.IO) { try { // Получаем размеры изображения @@ -1529,12 +1564,12 @@ val newList = messages + optimisticMessages // Генерируем blurhash val blurhash = com.rosetta.messenger.utils.MediaUtils.generateBlurhash(context, imageUri) - // 3. 🔄 Обновляем optimistic сообщение с реальными данными + // 4. 🔄 Обновляем optimistic сообщение с реальными данными withContext(Dispatchers.Main) { updateOptimisticImageMessage(messageId, imageBase64, blurhash, width, height) } - // 4. 📤 Отправляем (шифрование + загрузка на сервер) + // 5. 📤 Отправляем (шифрование + загрузка на сервер) sendImageMessageInternal( messageId = messageId, imageBase64 = imageBase64,