feat: Implement avatar handling and display across chat and account screens

This commit is contained in:
k1ngsterr1
2026-01-24 01:14:25 +05:00
parent 1367864008
commit 10c78e6231
7 changed files with 135 additions and 87 deletions

View File

@@ -6,6 +6,7 @@ import com.rosetta.messenger.crypto.CryptoManager
import com.rosetta.messenger.crypto.MessageCrypto
import com.rosetta.messenger.database.*
import com.rosetta.messenger.network.*
import com.rosetta.messenger.utils.AvatarFileManager
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import org.json.JSONArray
@@ -53,6 +54,7 @@ class MessageRepository private constructor(private val context: Context) {
private val database = RosettaDatabase.getDatabase(context)
private val messageDao = database.messageDao()
private val dialogDao = database.dialogDao()
private val avatarDao = database.avatarDao()
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
@@ -318,7 +320,10 @@ class MessageRepository private constructor(private val context: Context) {
privateKey
)
// 🔒 Шифруем plainMessage с использованием приватного ключа
// <EFBFBD> Обрабатываем AVATAR attachments - сохраняем аватар отправителя
processAvatarAttachments(packet.attachments, packet.fromPublicKey, packet.chachaKey, privateKey)
// <20>🔒 Шифруем plainMessage с использованием приватного ключа
val encryptedPlainMessage = CryptoManager.encryptWithPassword(plainText, privateKey)
// Создаем entity для кэша и возможной вставки
@@ -719,6 +724,61 @@ class MessageRepository private constructor(private val context: Context) {
return jsonArray.toString()
}
/**
* 📸 Обработка AVATAR attachments - сохранение аватара отправителя в кэш
* Как в desktop: при получении attachment с типом AVATAR - сохраняем в avatar_cache
*/
private suspend fun processAvatarAttachments(
attachments: List<MessageAttachment>,
fromPublicKey: String,
encryptedKey: String,
privateKey: String
) {
Log.d("MessageRepository", "📸 processAvatarAttachments: ${attachments.size} attachments from ${fromPublicKey.take(16)}")
for (attachment in attachments) {
Log.d("MessageRepository", "📸 Attachment type=${attachment.type} (AVATAR=${AttachmentType.AVATAR}), blob size=${attachment.blob.length}")
if (attachment.type == AttachmentType.AVATAR && attachment.blob.isNotEmpty()) {
try {
Log.d("MessageRepository", "📸 Found AVATAR attachment! Decrypting...")
// 1. Расшифровываем blob с ChaCha ключом сообщения
val decryptedBlob = MessageCrypto.decryptAttachmentBlob(
attachment.blob,
encryptedKey,
privateKey
)
Log.d("MessageRepository", "📸 Decrypted blob: ${decryptedBlob?.take(50) ?: "NULL"}")
if (decryptedBlob != null) {
// 2. Сохраняем аватар в кэш
val filePath = AvatarFileManager.saveAvatar(context, decryptedBlob, fromPublicKey)
Log.d("MessageRepository", "📸 Avatar saved to: $filePath")
val entity = AvatarCacheEntity(
publicKey = fromPublicKey,
avatar = filePath,
timestamp = System.currentTimeMillis()
)
avatarDao.insertAvatar(entity)
Log.d("MessageRepository", "📸 Avatar inserted to DB for ${fromPublicKey.take(16)}")
// 3. Очищаем старые аватары (оставляем последние 5)
avatarDao.deleteOldAvatars(fromPublicKey, 5)
Log.d("MessageRepository", "📸 ✅ Successfully saved avatar for $fromPublicKey")
} else {
Log.w("MessageRepository", "📸 ⚠️ Decryption returned null!")
}
} catch (e: Exception) {
Log.e("MessageRepository", "📸 ❌ Failed to process avatar attachment", e)
}
}
}
}
/**
* Сериализация attachments в JSON с RE-ENCRYPTION для хранения в БД
* Для MESSAGES типа: