feat: Implement read receipt handling and mark all outgoing messages as read
This commit is contained in:
@@ -134,17 +134,28 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
|
||||
}
|
||||
}
|
||||
|
||||
// Прочитано
|
||||
// Прочитано - пакет сообщает что собеседник прочитал наши сообщения
|
||||
// В Desktop нет messageId - просто отмечаем все исходящие сообщения как прочитанные
|
||||
ProtocolManager.waitPacket(0x07) { packet ->
|
||||
val readPacket = packet as PacketRead
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
// Обновляем в БД
|
||||
updateMessageStatusInDb(readPacket.messageId, 3) // READ
|
||||
// Обновляем UI
|
||||
withContext(Dispatchers.Main) {
|
||||
updateMessageStatus(readPacket.messageId, MessageStatus.READ)
|
||||
// Если fromPublicKey == наш собеседник, значит он прочитал наши сообщения
|
||||
if (readPacket.fromPublicKey == opponentKey) {
|
||||
// Обновляем все непрочитанные исходящие сообщения в БД
|
||||
val account = myPublicKey ?: return@launch
|
||||
val opponent = opponentKey ?: return@launch
|
||||
messageDao.markAllAsRead(account, opponent)
|
||||
|
||||
// Обновляем UI - все исходящие сообщения помечаем как прочитанные
|
||||
withContext(Dispatchers.Main) {
|
||||
_messages.value = _messages.value.map { msg ->
|
||||
if (msg.isOutgoing && msg.status != MessageStatus.READ) {
|
||||
msg.copy(status = MessageStatus.READ)
|
||||
} else msg
|
||||
}
|
||||
}
|
||||
ProtocolManager.addLog("✓✓ Read receipt from: ${readPacket.fromPublicKey.take(8)}...")
|
||||
}
|
||||
ProtocolManager.addLog("✓✓ Read: ${readPacket.messageId.take(8)}...")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -762,29 +773,31 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
/**
|
||||
* 👁️ Отправить подтверждение о прочтении сообщения
|
||||
* В Desktop PacketRead не содержит messageId - он просто сообщает что мы прочитали сообщения
|
||||
*/
|
||||
fun sendReadReceipt(messageId: String, senderPublicKey: String) {
|
||||
// Не отправляем повторно
|
||||
if (sentReadReceipts.contains(messageId)) return
|
||||
// Не отправляем повторно для этого собеседника
|
||||
val receiptKey = senderPublicKey
|
||||
if (sentReadReceipts.contains(receiptKey)) return
|
||||
|
||||
val sender = myPublicKey ?: return
|
||||
val privateKey = myPrivateKey ?: return
|
||||
|
||||
sentReadReceipts.add(messageId)
|
||||
sentReadReceipts.add(receiptKey)
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val privateKeyHash = CryptoManager.generatePrivateKeyHash(privateKey)
|
||||
|
||||
// Desktop формат: privateKey, fromPublicKey, toPublicKey
|
||||
val packet = PacketRead().apply {
|
||||
this.messageId = messageId
|
||||
fromPublicKey = sender
|
||||
toPublicKey = senderPublicKey
|
||||
this.privateKey = privateKeyHash
|
||||
fromPublicKey = sender // Мы (кто прочитал)
|
||||
toPublicKey = senderPublicKey // Кому отправляем уведомление
|
||||
}
|
||||
|
||||
ProtocolManager.send(packet)
|
||||
ProtocolManager.addLog("👁️ Read receipt sent for: ${messageId.take(8)}...")
|
||||
ProtocolManager.addLog("👁️ Read receipt sent to: ${senderPublicKey.take(8)}...")
|
||||
|
||||
// Обновляем в БД что сообщение прочитано
|
||||
updateMessageReadInDb(messageId)
|
||||
|
||||
Reference in New Issue
Block a user