Улучшена обработка звонков и вложений: нормализация входящих аттачментов, обновление UI карточек звонков
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -844,17 +844,20 @@ class MessageRepository private constructor(private val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
val normalizedIncomingAttachments =
|
||||
normalizeIncomingAttachments(packet.attachments, plainText)
|
||||
|
||||
// 📝 LOG: Расшифровка успешна
|
||||
MessageLogger.logDecryptionSuccess(
|
||||
messageId = messageId,
|
||||
plainTextLength = plainText.length,
|
||||
attachmentsCount = packet.attachments.size
|
||||
attachmentsCount = normalizedIncomingAttachments.size
|
||||
)
|
||||
|
||||
// Сериализуем attachments в JSON с расшифровкой MESSAGES blob
|
||||
val attachmentsJson =
|
||||
serializeAttachmentsWithDecryption(
|
||||
packet.attachments,
|
||||
normalizedIncomingAttachments,
|
||||
packet.chachaKey,
|
||||
privateKey,
|
||||
plainKeyAndNonce,
|
||||
@@ -863,7 +866,7 @@ class MessageRepository private constructor(private val context: Context) {
|
||||
|
||||
// 🖼️ Обрабатываем IMAGE attachments - сохраняем в файл (как в desktop)
|
||||
processImageAttachments(
|
||||
packet.attachments,
|
||||
normalizedIncomingAttachments,
|
||||
packet.chachaKey,
|
||||
privateKey,
|
||||
plainKeyAndNonce,
|
||||
@@ -876,7 +879,7 @@ class MessageRepository private constructor(private val context: Context) {
|
||||
val avatarOwnerKey =
|
||||
if (isGroupMessage) toGroupDialogPublicKey(packet.toPublicKey) else packet.fromPublicKey
|
||||
processAvatarAttachments(
|
||||
packet.attachments,
|
||||
normalizedIncomingAttachments,
|
||||
avatarOwnerKey,
|
||||
packet.chachaKey,
|
||||
privateKey,
|
||||
@@ -917,7 +920,7 @@ class MessageRepository private constructor(private val context: Context) {
|
||||
plainMessage = encryptedPlainMessage, // 🔒 Зашифрованный текст
|
||||
attachments = attachmentsJson,
|
||||
primaryAttachmentType =
|
||||
resolvePrimaryAttachmentType(packet.attachments),
|
||||
resolvePrimaryAttachmentType(normalizedIncomingAttachments),
|
||||
dialogKey = dialogKey
|
||||
)
|
||||
|
||||
@@ -1703,6 +1706,50 @@ class MessageRepository private constructor(private val context: Context) {
|
||||
return attachments.first().type.value
|
||||
}
|
||||
|
||||
/**
|
||||
* Desktop иногда присылает attachment звонка с некорректным type при поврежденном/пограничном
|
||||
* пакете (в UI это превращается в пустой пузырь). Для attachment-only сообщения мягко
|
||||
* нормализуем такой кейс к CALL.
|
||||
*/
|
||||
private fun normalizeIncomingAttachments(
|
||||
attachments: List<MessageAttachment>,
|
||||
plainText: String
|
||||
): List<MessageAttachment> {
|
||||
if (attachments.isEmpty() || plainText.isNotBlank() || attachments.size != 1) {
|
||||
return attachments
|
||||
}
|
||||
|
||||
val first = attachments.first()
|
||||
if (!isLikelyCallAttachment(first, plainText)) {
|
||||
return attachments
|
||||
}
|
||||
|
||||
return when (first.type) {
|
||||
AttachmentType.CALL -> attachments
|
||||
else -> {
|
||||
MessageLogger.debug(
|
||||
"📥 ATTACHMENT FIXUP: coerced ${first.type} -> CALL for ${first.id.take(8)}..."
|
||||
)
|
||||
listOf(first.copy(type = AttachmentType.CALL))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isLikelyCallAttachment(attachment: MessageAttachment, plainText: String): Boolean {
|
||||
if (plainText.isNotBlank()) return false
|
||||
if (attachment.blob.isNotBlank()) return false
|
||||
if (attachment.width > 0 || attachment.height > 0) return false
|
||||
|
||||
val preview = attachment.preview.trim()
|
||||
if (preview.isEmpty()) return true
|
||||
|
||||
val tail = preview.substringAfterLast("::", preview).trim()
|
||||
if (tail.toIntOrNull() != null) return true
|
||||
|
||||
return Regex("duration(?:Sec|Seconds)?\\s*[:=]\\s*\\d+", RegexOption.IGNORE_CASE)
|
||||
.containsMatchIn(preview)
|
||||
}
|
||||
|
||||
private suspend fun upsertSearchIndex(account: String, entity: MessageEntity, plainText: String) {
|
||||
val opponentKey =
|
||||
if (entity.fromMe == 1) entity.toPublicKey.trim() else entity.fromPublicKey.trim()
|
||||
|
||||
Reference in New Issue
Block a user