feat: Enhance logging in MessageRepository and ChatsListViewModel for better debugging and flow tracking
This commit is contained in:
@@ -75,23 +75,44 @@ class MessageRepository private constructor(private val context: Context) {
|
||||
INSTANCE ?: MessageRepository(context.applicationContext).also { INSTANCE = it }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерация детерминированного messageId на основе данных сообщения
|
||||
* Аналог generateRandomKeyFormSeed из Архива
|
||||
*/
|
||||
fun generateMessageId(fromPublicKey: String, toPublicKey: String, timestamp: Long): String {
|
||||
val seed = fromPublicKey + toPublicKey + timestamp.toString()
|
||||
val hash = java.security.MessageDigest.getInstance("SHA-256")
|
||||
.digest(seed.toByteArray())
|
||||
// Берём первые 16 символов hex-представления
|
||||
return hash.take(8).joinToString("") { String.format("%02x", it) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализация с текущим аккаунтом
|
||||
*/
|
||||
fun initialize(publicKey: String, privateKey: String) {
|
||||
android.util.Log.d("MessageRepository", "🔐 initialize() called with publicKey: ${publicKey.take(16)}...")
|
||||
currentAccount = publicKey
|
||||
currentPrivateKey = privateKey
|
||||
|
||||
// Загрузка диалогов
|
||||
scope.launch {
|
||||
dialogDao.getDialogsFlow(publicKey).collect { entities ->
|
||||
android.util.Log.d("MessageRepository", "📋 MessageRepository dialogsFlow emitted: ${entities.size} dialogs")
|
||||
_dialogs.value = entities.map { it.toDialog() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверка инициализации
|
||||
*/
|
||||
fun isInitialized(): Boolean {
|
||||
return currentAccount != null && currentPrivateKey != null
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить поток сообщений для диалога
|
||||
*/
|
||||
@@ -210,13 +231,39 @@ class MessageRepository private constructor(private val context: Context) {
|
||||
* Обработка входящего сообщения
|
||||
*/
|
||||
suspend fun handleIncomingMessage(packet: PacketMessage) {
|
||||
val account = currentAccount ?: return
|
||||
val privateKey = currentPrivateKey ?: return
|
||||
android.util.Log.d("MessageRepository", "═══════════════════════════════════════")
|
||||
android.util.Log.d("MessageRepository", "📩 handleIncomingMessage START")
|
||||
android.util.Log.d("MessageRepository", " from: ${packet.fromPublicKey.take(20)}...")
|
||||
|
||||
// Проверяем, не дубликат ли
|
||||
if (messageDao.messageExists(account, packet.messageId)) return
|
||||
// 🔥 Генерируем messageId если он пустой (как в Архиве - generateRandomKeyFormSeed)
|
||||
val messageId = if (packet.messageId.isBlank()) {
|
||||
generateMessageId(packet.fromPublicKey, packet.toPublicKey, packet.timestamp)
|
||||
} else {
|
||||
packet.messageId
|
||||
}
|
||||
android.util.Log.d("MessageRepository", " messageId: $messageId (original: ${packet.messageId})")
|
||||
android.util.Log.d("MessageRepository", " currentAccount: ${currentAccount?.take(20) ?: "NULL"}...")
|
||||
android.util.Log.d("MessageRepository", " currentPrivateKey: ${if (currentPrivateKey != null) "SET" else "NULL"}")
|
||||
|
||||
val account = currentAccount ?: run {
|
||||
android.util.Log.e("MessageRepository", "❌ ABORT: currentAccount is NULL!")
|
||||
return
|
||||
}
|
||||
val privateKey = currentPrivateKey ?: run {
|
||||
android.util.Log.e("MessageRepository", "❌ ABORT: currentPrivateKey is NULL!")
|
||||
return
|
||||
}
|
||||
|
||||
// Проверяем, не дубликат ли (используем сгенерированный messageId)
|
||||
val isDuplicate = messageDao.messageExists(account, messageId)
|
||||
android.util.Log.d("MessageRepository", " isDuplicate: $isDuplicate")
|
||||
if (isDuplicate) {
|
||||
android.util.Log.d("MessageRepository", "⚠️ Skipping duplicate message")
|
||||
return
|
||||
}
|
||||
|
||||
val dialogKey = getDialogKey(packet.fromPublicKey)
|
||||
android.util.Log.d("MessageRepository", " dialogKey: $dialogKey")
|
||||
|
||||
try {
|
||||
// Расшифровываем
|
||||
@@ -247,21 +294,25 @@ class MessageRepository private constructor(private val context: Context) {
|
||||
read = 0,
|
||||
fromMe = 0,
|
||||
delivered = DeliveryStatus.DELIVERED.value,
|
||||
messageId = packet.messageId,
|
||||
messageId = messageId, // 🔥 Используем сгенерированный messageId!
|
||||
plainMessage = encryptedPlainMessage, // 🔒 Зашифрованный текст
|
||||
attachments = attachmentsJson,
|
||||
dialogKey = dialogKey
|
||||
)
|
||||
messageDao.insertMessage(entity)
|
||||
android.util.Log.d("MessageRepository", "✅ Message saved to DB: ${packet.messageId.take(16)}...")
|
||||
|
||||
// Обновляем диалог
|
||||
android.util.Log.d("MessageRepository", "🔄 Calling updateDialog for ${packet.fromPublicKey.take(16)}...")
|
||||
updateDialog(packet.fromPublicKey, plainText, packet.timestamp, incrementUnread = true)
|
||||
android.util.Log.d("MessageRepository", "✅ updateDialog completed!")
|
||||
|
||||
// Обновляем кэш
|
||||
val message = entity.toMessage()
|
||||
updateMessageCache(dialogKey, message)
|
||||
|
||||
} catch (e: Exception) {
|
||||
android.util.Log.e("MessageRepository", "❌ Error handling incoming message", e)
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
@@ -301,13 +352,20 @@ class MessageRepository private constructor(private val context: Context) {
|
||||
|
||||
/**
|
||||
* Отметить диалог как прочитанный
|
||||
* 🔥 После обновления messages обновляем диалог через updateDialogFromMessages
|
||||
*/
|
||||
suspend fun markDialogAsRead(opponentKey: String) {
|
||||
val account = currentAccount ?: return
|
||||
val dialogKey = getDialogKey(opponentKey)
|
||||
|
||||
// Отмечаем сообщения как прочитанные
|
||||
messageDao.markDialogAsRead(account, dialogKey)
|
||||
dialogDao.clearUnreadCount(account, opponentKey)
|
||||
|
||||
// 🔥 КРИТИЧНО: Пересчитываем счетчики из таблицы messages
|
||||
// чтобы unread_count обновился моментально
|
||||
dialogDao.updateDialogFromMessages(account, opponentKey)
|
||||
|
||||
android.util.Log.d("MessageRepository", "✅ Dialog marked as read and updated from messages")
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -392,21 +450,42 @@ class MessageRepository private constructor(private val context: Context) {
|
||||
incrementUnread: Boolean = false
|
||||
) {
|
||||
val account = currentAccount ?: return
|
||||
val privateKey = currentPrivateKey ?: return
|
||||
|
||||
val existing = dialogDao.getDialog(account, opponentKey)
|
||||
if (existing != null) {
|
||||
dialogDao.updateLastMessage(account, opponentKey, lastMessage, timestamp)
|
||||
if (incrementUnread) {
|
||||
dialogDao.incrementUnreadCount(account, opponentKey)
|
||||
android.util.Log.d("MessageRepository", "📝 Updating dialog for ${opponentKey.take(16)}...")
|
||||
android.util.Log.d("MessageRepository", " lastMessage: ${lastMessage.take(50)}")
|
||||
|
||||
try {
|
||||
// 🔥 КРИТИЧНО: Сначала считаем реальное количество непрочитанных из messages
|
||||
val unreadCount = messageDao.getUnreadCountForDialog(account, opponentKey)
|
||||
android.util.Log.d("MessageRepository", " unreadCount from messages: $unreadCount")
|
||||
|
||||
// 🔒 Шифруем lastMessage
|
||||
val encryptedLastMessage = CryptoManager.encryptWithPassword(lastMessage, privateKey)
|
||||
|
||||
// Проверяем существует ли диалог
|
||||
val existing = dialogDao.getDialog(account, opponentKey)
|
||||
|
||||
if (existing != null) {
|
||||
// Обновляем существующий диалог
|
||||
android.util.Log.d("MessageRepository", " ✏️ Updating existing dialog...")
|
||||
dialogDao.updateLastMessage(account, opponentKey, encryptedLastMessage, timestamp)
|
||||
dialogDao.updateUnreadCount(account, opponentKey, unreadCount)
|
||||
} else {
|
||||
// Создаем новый диалог
|
||||
android.util.Log.d("MessageRepository", " ➕ Creating new dialog...")
|
||||
dialogDao.insertDialog(DialogEntity(
|
||||
account = account,
|
||||
opponentKey = opponentKey,
|
||||
lastMessage = encryptedLastMessage,
|
||||
lastMessageTimestamp = timestamp,
|
||||
unreadCount = unreadCount
|
||||
))
|
||||
}
|
||||
} else {
|
||||
dialogDao.insertDialog(DialogEntity(
|
||||
account = account,
|
||||
opponentKey = opponentKey,
|
||||
lastMessage = lastMessage,
|
||||
lastMessageTimestamp = timestamp,
|
||||
unreadCount = if (incrementUnread) 1 else 0
|
||||
))
|
||||
|
||||
android.util.Log.d("MessageRepository", " ✅ Dialog updated successfully!")
|
||||
} catch (e: Exception) {
|
||||
android.util.Log.e("MessageRepository", " ❌ Error updating dialog", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user