feat: Preserve optimistic message status during UI updates for improved user experience
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user