feat: Enhance logging in MessageRepository and ChatsListViewModel for better debugging and flow tracking
This commit is contained in:
@@ -464,7 +464,8 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
|
||||
launch(Dispatchers.IO) {
|
||||
// Отмечаем как прочитанные в БД
|
||||
messageDao.markDialogAsRead(account, dialogKey)
|
||||
dialogDao.clearUnreadCount(account, opponent)
|
||||
// 🔥 Пересчитываем счетчики из messages
|
||||
dialogDao.updateDialogFromMessages(account, opponent)
|
||||
|
||||
// Отправляем read receipt собеседнику
|
||||
if (messages.isNotEmpty()) {
|
||||
@@ -519,7 +520,8 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
// Фоновые операции
|
||||
messageDao.markDialogAsRead(account, dialogKey)
|
||||
dialogDao.clearUnreadCount(account, opponent)
|
||||
// 🔥 Пересчитываем счетчики из messages
|
||||
dialogDao.updateDialogFromMessages(account, opponent)
|
||||
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
@@ -1013,33 +1015,18 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
/**
|
||||
* Сохранить диалог в базу данных
|
||||
* 🔒 lastMessage шифруется для безопасного хранения
|
||||
* <EFBFBD> Используем updateDialogFromMessages для пересчета счетчиков из messages
|
||||
*/
|
||||
private suspend fun saveDialog(lastMessage: String, timestamp: Long) {
|
||||
val account = myPublicKey ?: return
|
||||
val opponent = opponentKey ?: return
|
||||
val privateKey = myPrivateKey ?: return
|
||||
|
||||
try {
|
||||
// 🔒 Шифруем lastMessage перед сохранением
|
||||
val encryptedLastMessage = CryptoManager.encryptWithPassword(lastMessage, privateKey)
|
||||
// 🔥 КРИТИЧНО: Используем updateDialogFromMessages который пересчитывает счетчики
|
||||
// напрямую из таблицы messages, как в Архиве!
|
||||
dialogDao.updateDialogFromMessages(account, opponent)
|
||||
|
||||
val existingDialog = dialogDao.getDialog(account, opponent)
|
||||
|
||||
if (existingDialog != null) {
|
||||
// Обновляем последнее сообщение
|
||||
dialogDao.updateLastMessage(account, opponent, encryptedLastMessage, timestamp)
|
||||
} else {
|
||||
// Создаём новый диалог
|
||||
dialogDao.insertDialog(DialogEntity(
|
||||
account = account,
|
||||
opponentKey = opponent,
|
||||
opponentTitle = opponentTitle,
|
||||
opponentUsername = opponentUsername,
|
||||
lastMessage = encryptedLastMessage,
|
||||
lastMessageTimestamp = timestamp
|
||||
))
|
||||
}
|
||||
Log.d(TAG, "✅ Dialog saved/updated from messages table")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Dialog save error", e)
|
||||
}
|
||||
@@ -1050,34 +1037,14 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
|
||||
*/
|
||||
private suspend fun updateDialog(opponentKey: String, lastMessage: String, timestamp: Long, incrementUnread: Boolean) {
|
||||
val account = myPublicKey ?: return
|
||||
val privateKey = myPrivateKey ?: return
|
||||
|
||||
try {
|
||||
// 🔒 Шифруем lastMessage для диалога
|
||||
val encryptedLastMessage = CryptoManager.encryptWithPassword(lastMessage, privateKey)
|
||||
// 🔥 КРИТИЧНО: Используем updateDialogFromMessages который пересчитывает счетчики
|
||||
// напрямую из таблицы messages, как в Архиве!
|
||||
// Это гарантирует что unread_count всегда соответствует реальному количеству непрочитанных
|
||||
dialogDao.updateDialogFromMessages(account, opponentKey)
|
||||
|
||||
val existingDialog = dialogDao.getDialog(account, opponentKey)
|
||||
|
||||
if (existingDialog != null) {
|
||||
// Обновляем последнее сообщение
|
||||
dialogDao.updateLastMessage(account, opponentKey, encryptedLastMessage, timestamp)
|
||||
|
||||
// Инкрементируем непрочитанные если нужно
|
||||
if (incrementUnread) {
|
||||
dialogDao.incrementUnreadCount(account, opponentKey)
|
||||
}
|
||||
} else {
|
||||
// Создаём новый диалог
|
||||
dialogDao.insertDialog(DialogEntity(
|
||||
account = account,
|
||||
opponentKey = opponentKey,
|
||||
opponentTitle = opponentTitle,
|
||||
opponentUsername = opponentUsername,
|
||||
lastMessage = encryptedLastMessage, // 🔒 Зашифрованный
|
||||
lastMessageTimestamp = timestamp,
|
||||
unreadCount = if (incrementUnread) 1 else 0
|
||||
))
|
||||
}
|
||||
Log.d(TAG, "✅ Dialog updated from messages table for $opponentKey")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "updateDialog error", e)
|
||||
}
|
||||
@@ -1252,12 +1219,13 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) {
|
||||
if (lastIncoming.timestamp.time <= lastReadMessageTimestamp) return
|
||||
|
||||
|
||||
// Отмечаем в БД и очищаем счетчик непрочитанных
|
||||
// Отмечаем в БД и пересчитываем счетчики
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val dialogKey = getDialogKey(account, opponent)
|
||||
messageDao.markDialogAsRead(account, dialogKey)
|
||||
dialogDao.clearUnreadCount(account, opponent)
|
||||
// 🔥 Пересчитываем счетчики из messages
|
||||
dialogDao.updateDialogFromMessages(account, opponent)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Mark as read error", e)
|
||||
}
|
||||
|
||||
@@ -54,14 +54,20 @@ class ChatsListViewModel(application: Application) : AndroidViewModel(applicatio
|
||||
* Установить текущий аккаунт и загрузить диалоги
|
||||
*/
|
||||
fun setAccount(publicKey: String, privateKey: String) {
|
||||
if (currentAccount == publicKey) return
|
||||
if (currentAccount == publicKey) {
|
||||
android.util.Log.d("ChatsListViewModel", "⚠️ setAccount called again for same account, skipping")
|
||||
return
|
||||
}
|
||||
currentAccount = publicKey
|
||||
currentPrivateKey = privateKey
|
||||
|
||||
android.util.Log.d("ChatsListViewModel", "✅ Setting up dialogs Flow for account: ${publicKey.take(16)}...")
|
||||
|
||||
viewModelScope.launch {
|
||||
dialogDao.getDialogsFlow(publicKey)
|
||||
.flowOn(Dispatchers.IO) // 🚀 Flow работает на IO
|
||||
.map { dialogsList ->
|
||||
android.util.Log.d("ChatsListViewModel", "📋 Dialogs Flow emitted: ${dialogsList.size} dialogs")
|
||||
// 🔓 Расшифровываем lastMessage на IO потоке (PBKDF2 - тяжелая операция!)
|
||||
dialogsList.map { dialog ->
|
||||
val decryptedLastMessage = try {
|
||||
@@ -91,7 +97,9 @@ class ChatsListViewModel(application: Application) : AndroidViewModel(applicatio
|
||||
}
|
||||
}
|
||||
.flowOn(Dispatchers.Default) // 🚀 map выполняется на Default (CPU)
|
||||
.flowOn(Dispatchers.Main) // 🎯 КРИТИЧНО: Обновляем UI на главном потоке!
|
||||
.collect { decryptedDialogs ->
|
||||
android.util.Log.d("ChatsListViewModel", "✅ Updated UI with ${decryptedDialogs.size} decrypted dialogs")
|
||||
_dialogs.value = decryptedDialogs
|
||||
|
||||
// 🟢 Подписываемся на онлайн-статусы всех собеседников
|
||||
@@ -125,6 +133,7 @@ class ChatsListViewModel(application: Application) : AndroidViewModel(applicatio
|
||||
|
||||
/**
|
||||
* Создать или обновить диалог после отправки/получения сообщения
|
||||
* 🔥 Используем updateDialogFromMessages для пересчета счетчиков из messages
|
||||
*/
|
||||
suspend fun upsertDialog(
|
||||
opponentKey: String,
|
||||
@@ -136,31 +145,20 @@ class ChatsListViewModel(application: Application) : AndroidViewModel(applicatio
|
||||
isOnline: Int = 0
|
||||
) {
|
||||
if (currentAccount.isEmpty()) return
|
||||
val privateKey = currentPrivateKey ?: return
|
||||
|
||||
// 🔒 Шифруем lastMessage перед сохранением
|
||||
val encryptedLastMessage = CryptoManager.encryptWithPassword(lastMessage, privateKey)
|
||||
|
||||
val existingDialog = dialogDao.getDialog(currentAccount, opponentKey)
|
||||
|
||||
if (existingDialog != null) {
|
||||
// Обновляем
|
||||
dialogDao.updateLastMessage(currentAccount, opponentKey, encryptedLastMessage, timestamp)
|
||||
try {
|
||||
// 🔥 КРИТИЧНО: Используем updateDialogFromMessages который пересчитывает счетчики
|
||||
// напрямую из таблицы messages, как в Архиве!
|
||||
dialogDao.updateDialogFromMessages(currentAccount, opponentKey)
|
||||
|
||||
// Обновляем информацию о собеседнике если есть
|
||||
if (opponentTitle.isNotEmpty()) {
|
||||
dialogDao.updateOpponentInfo(currentAccount, opponentKey, opponentTitle, opponentUsername, verified)
|
||||
}
|
||||
} else {
|
||||
// Создаём новый
|
||||
dialogDao.insertDialog(DialogEntity(
|
||||
account = currentAccount,
|
||||
opponentKey = opponentKey,
|
||||
opponentTitle = opponentTitle,
|
||||
opponentUsername = opponentUsername,
|
||||
lastMessage = encryptedLastMessage, // 🔒 Зашифрованный
|
||||
lastMessageTimestamp = timestamp,
|
||||
verified = verified,
|
||||
isOnline = isOnline
|
||||
))
|
||||
|
||||
android.util.Log.d("ChatsListViewModel", "✅ Dialog upserted from messages table")
|
||||
} catch (e: Exception) {
|
||||
android.util.Log.e("ChatsListViewModel", "Error upserting dialog", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user