Синхронизация статусов и времени существующих сообщений, добавление новых сообщений в кэш
Some checks failed
Android Kernel Build / build (push) Has been cancelled
Some checks failed
Android Kernel Build / build (push) Has been cancelled
This commit is contained in:
@@ -902,37 +902,60 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
// 🔥 Берём ТЕКУЩЕЕ состояние UI (может уже содержать новые сообщения)
|
// 🔥 Берём ТЕКУЩЕЕ состояние UI (может уже содержать новые сообщения)
|
||||||
val currentMessages = _messages.value
|
val currentMessages = _messages.value
|
||||||
val existingIds = currentMessages.map { it.id }.toSet()
|
val existingIds = currentMessages.map { it.id }.toSet()
|
||||||
|
val entitiesById = entities.associateBy { it.messageId }
|
||||||
|
|
||||||
|
// 🔄 Синхронизируем статусы/время уже существующих сообщений из БД.
|
||||||
|
// Это критично для случая WAITING -> ERROR: без этого в открытом диалоге остаются "часики".
|
||||||
|
val reconciledMessages =
|
||||||
|
currentMessages.map { message ->
|
||||||
|
val entity = entitiesById[message.id] ?: return@map message
|
||||||
|
|
||||||
|
val dbStatus =
|
||||||
|
when (entity.delivered) {
|
||||||
|
0 -> MessageStatus.SENDING
|
||||||
|
1 -> if (entity.read == 1) MessageStatus.READ else MessageStatus.DELIVERED
|
||||||
|
2 -> MessageStatus.ERROR
|
||||||
|
3 -> MessageStatus.READ
|
||||||
|
else -> MessageStatus.SENT
|
||||||
|
}
|
||||||
|
|
||||||
|
var updatedMessage = message
|
||||||
|
if (updatedMessage.status != dbStatus) {
|
||||||
|
updatedMessage = updatedMessage.copy(status = dbStatus)
|
||||||
|
}
|
||||||
|
if (updatedMessage.timestamp.time != entity.timestamp) {
|
||||||
|
updatedMessage = updatedMessage.copy(timestamp = Date(entity.timestamp))
|
||||||
|
}
|
||||||
|
updatedMessage
|
||||||
|
}
|
||||||
|
val hasExistingUpdates = reconciledMessages != currentMessages
|
||||||
|
|
||||||
// 🔥 Находим только НОВЫЕ сообщения (которых нет в текущем UI)
|
// 🔥 Находим только НОВЫЕ сообщения (которых нет в текущем UI)
|
||||||
val newEntities = entities.filter { it.messageId !in existingIds }
|
val newEntities = entities.filter { it.messageId !in existingIds }
|
||||||
|
|
||||||
if (newEntities.isNotEmpty()) {
|
val newMessages =
|
||||||
val semaphore = Semaphore(DECRYPT_PARALLELISM)
|
if (newEntities.isNotEmpty()) {
|
||||||
val newMessages = coroutineScope {
|
val semaphore = Semaphore(DECRYPT_PARALLELISM)
|
||||||
newEntities
|
coroutineScope {
|
||||||
.map { entity ->
|
newEntities
|
||||||
async { semaphore.withPermit { entityToChatMessage(entity) } }
|
.map { entity ->
|
||||||
}
|
async { semaphore.withPermit { entityToChatMessage(entity) } }
|
||||||
.awaitAll()
|
}
|
||||||
}
|
.awaitAll()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
// 🔥 ДОБАВЛЯЕМ новые к текущим, а не заменяем!
|
if (hasExistingUpdates || newMessages.isNotEmpty()) {
|
||||||
// Сортируем по timestamp чтобы новые были в конце
|
// 🔥 ДОБАВЛЯЕМ новые + применяем статусные апдейты к существующим
|
||||||
val updatedMessages =
|
val updatedMessages =
|
||||||
sortMessagesAscending((currentMessages + newMessages).distinctBy { it.id })
|
sortMessagesAscending((reconciledMessages + newMessages).distinctBy { it.id })
|
||||||
|
|
||||||
// 🔥 ИСПРАВЛЕНИЕ: Обновляем кэш сохраняя ВСЕ сообщения, не только отображаемые!
|
// 🔥 Обновляем кэш: сохраняем старые страницы + применяем новые статусы/время
|
||||||
// Объединяем существующий кэш с новыми сообщениями
|
|
||||||
val existingCache = dialogMessagesCache[cacheKey(account, dialogKey)] ?: emptyList()
|
val existingCache = dialogMessagesCache[cacheKey(account, dialogKey)] ?: emptyList()
|
||||||
val allCachedIds = existingCache.map { it.id }.toSet()
|
val mergedCache = sortMessagesAscending((existingCache + updatedMessages).distinctBy { it.id })
|
||||||
val trulyNewMessages = newMessages.filter { it.id !in allCachedIds }
|
updateCacheWithLimit(account, dialogKey, mergedCache)
|
||||||
if (trulyNewMessages.isNotEmpty()) {
|
|
||||||
updateCacheWithLimit(
|
|
||||||
account,
|
|
||||||
dialogKey,
|
|
||||||
sortMessagesAscending(existingCache + trulyNewMessages)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
withContext(Dispatchers.Main.immediate) { _messages.value = updatedMessages }
|
withContext(Dispatchers.Main.immediate) { _messages.value = updatedMessages }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user