Исправлены синхронизация групп, выделение сообщений и фон чата

This commit is contained in:
2026-03-07 23:43:09 +05:00
parent 364b166581
commit 85bddb798c
8 changed files with 352 additions and 32 deletions

View File

@@ -1,6 +1,7 @@
package com.rosetta.messenger.data
import android.content.Context
import android.util.Log
import com.rosetta.messenger.crypto.CryptoManager
import com.rosetta.messenger.database.GroupEntity
import com.rosetta.messenger.database.MessageEntity
@@ -23,6 +24,7 @@ import kotlin.coroutines.resume
class GroupRepository private constructor(context: Context) {
private val appContext = context.applicationContext
private val db = RosettaDatabase.getDatabase(context.applicationContext)
private val groupDao = db.groupDao()
private val messageDao = db.messageDao()
@@ -31,9 +33,11 @@ class GroupRepository private constructor(context: Context) {
private val inviteInfoCache = ConcurrentHashMap<String, GroupInviteInfoResult>()
companion object {
private const val TAG = "GroupRepository"
private const val GROUP_PREFIX = "#group:"
private const val GROUP_INVITE_PASSWORD = "rosetta_group"
private const val GROUP_WAIT_TIMEOUT_MS = 15_000L
private const val GROUP_CREATED_MARKER = "\$a=Group created"
@Volatile
private var INSTANCE: GroupRepository? = null
@@ -232,7 +236,20 @@ class GroupRepository private constructor(context: Context) {
return GroupJoinResult(success = false, error = "Failed to construct invite")
}
return joinGroup(accountPublicKey, accountPrivateKey, invite)
val joinResult = joinGroup(accountPublicKey, accountPrivateKey, invite)
if (joinResult.success) {
val dialogPublicKey = joinResult.dialogPublicKey
if (!dialogPublicKey.isNullOrBlank()) {
emitGroupCreatedMarker(
accountPublicKey = accountPublicKey,
accountPrivateKey = accountPrivateKey,
dialogPublicKey = dialogPublicKey
)
}
}
return joinResult
}
suspend fun joinGroup(
@@ -455,6 +472,23 @@ class GroupRepository private constructor(context: Context) {
)
}
private suspend fun emitGroupCreatedMarker(
accountPublicKey: String,
accountPrivateKey: String,
dialogPublicKey: String
) {
try {
val messages = MessageRepository.getInstance(appContext)
messages.initialize(accountPublicKey, accountPrivateKey)
messages.sendMessage(
toPublicKey = dialogPublicKey,
text = GROUP_CREATED_MARKER
)
} catch (e: Exception) {
Log.w(TAG, "Failed to emit group-created marker for sync visibility", e)
}
}
private fun buildStoredGroupKey(groupKey: String, privateKey: String): String {
val encrypted = CryptoManager.encryptWithPassword(groupKey, privateKey)
return "group:$encrypted"

View File

@@ -767,7 +767,7 @@ class MessageRepository private constructor(private val context: Context) {
// 📸 Обрабатываем AVATAR attachments:
// в личке — сохраняем аватар отправителя, в группе — аватар группы (desktop parity)
val avatarOwnerKey =
if (isGroupMessage) packet.toPublicKey else packet.fromPublicKey
if (isGroupMessage) toGroupDialogPublicKey(packet.toPublicKey) else packet.fromPublicKey
processAvatarAttachments(
packet.attachments,
avatarOwnerKey,
@@ -1179,6 +1179,11 @@ class MessageRepository private constructor(private val context: Context) {
}
}
private fun toGroupDialogPublicKey(value: String): String {
val groupId = normalizeGroupId(value)
return if (groupId.isBlank()) value.trim() else "#group:$groupId"
}
private fun buildStoredGroupKey(groupKey: String, privateKey: String): String {
return "group:${CryptoManager.encryptWithPassword(groupKey, privateKey)}"
}