feat: Preserve optimistic message status during UI updates for improved user experience

This commit is contained in:
k1ngsterr1
2026-01-13 17:58:41 +05:00
parent d2eec2ab61
commit 4689dce862

View File

@@ -300,8 +300,18 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
// ProtocolManager.setupPacketHandlers() не вызывается, поэтому сохраняем сами
// Используем fromPublicKey как opponent для корректного dialogKey
val senderKey = packet.fromPublicKey
// 🔥 FIX: Если messageId пустой - генерируем новый UUID
val finalMessageId = if (packet.messageId.isNullOrEmpty()) {
UUID.randomUUID().toString().replace("-", "").take(32).also {
ProtocolManager.addLog("⚠️ Empty messageId from server, generated: ${it.take(8)}...")
}
} else {
packet.messageId
}
saveMessageToDatabase(
messageId = packet.messageId,
messageId = finalMessageId,
text = decryptedText,
encryptedContent = packet.content,
encryptedKey = packet.chachaKey,
@@ -441,8 +451,12 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
ProtocolManager.addLog("📋 Decrypted and loaded ${messages.size} messages from DB")
// 🔥 СРАЗУ обновляем UI - пользователь видит сообщения мгновенно
// НО сохраняем оптимистичные сообщения (SENDING), которые ещё не в БД
withContext(Dispatchers.Main.immediate) {
_messages.value = messages
val optimisticMessages = _messages.value.filter { msg ->
msg.status == MessageStatus.SENDING && messages.none { it.id == msg.id }
}
_messages.value = messages + optimisticMessages
_isLoading.value = false
}
@@ -1080,13 +1094,22 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
try {
val dialogKey = getDialogKey(account, opponent)
// 🔒 Проверяем messageId - если пустой, генерируем новый
val finalMessageId = if (messageId.isEmpty()) {
val generated = UUID.randomUUID().toString().replace("-", "").take(32)
ProtocolManager.addLog("⚠️ Empty messageId detected, generated new: $generated")
generated
} else {
messageId
}
// 🔒 Шифруем plainMessage с использованием приватного ключа
val encryptedPlainMessage = CryptoManager.encryptWithPassword(text, privateKey)
// Проверяем существует ли сообщение
val exists = messageDao.messageExists(account, messageId)
val exists = messageDao.messageExists(account, finalMessageId)
ProtocolManager.addLog("💾 Saving message to DB:")
ProtocolManager.addLog(" messageId: $messageId")
ProtocolManager.addLog(" messageId: $finalMessageId")
ProtocolManager.addLog(" exists in DB: $exists")
ProtocolManager.addLog(" dialogKey: $dialogKey")
ProtocolManager.addLog(" text: ${text.take(20)}...")
@@ -1101,7 +1124,7 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
read = if (isFromMe) 1 else 0,
fromMe = if (isFromMe) 1 else 0,
delivered = delivered,
messageId = messageId,
messageId = finalMessageId,
plainMessage = encryptedPlainMessage, // 🔒 Зашифрованный текст для хранения в БД
attachments = attachmentsJson,
replyToMessageId = null,