From c52e6dda53d6ba2979c326c35940c072a0c16bd0 Mon Sep 17 00:00:00 2001 From: k1ngsterr1 Date: Fri, 16 Jan 2026 05:57:30 +0500 Subject: [PATCH] feat: Enhance logging in scrollToMessage function for better debugging of message IDs and lengths --- .../messenger/database/MessageEntities.kt | 21 +++++++++++++ .../messenger/ui/chats/ChatDetailScreen.kt | 9 +++++- .../messenger/ui/chats/ChatViewModel.kt | 31 ++++++++++++++++--- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/rosetta/messenger/database/MessageEntities.kt b/app/src/main/java/com/rosetta/messenger/database/MessageEntities.kt index 46463c3..69a74fe 100644 --- a/app/src/main/java/com/rosetta/messenger/database/MessageEntities.kt +++ b/app/src/main/java/com/rosetta/messenger/database/MessageEntities.kt @@ -198,6 +198,27 @@ interface MessageDao { @Query("DELETE FROM messages WHERE account = :account AND message_id = :messageId") suspend fun deleteMessage(account: String, messageId: String) + /** + * Найти сообщение по публичному ключу отправителя и timestamp (для reply) + * Ищет с допуском по времени для учета возможных рассинхронизаций + */ + @Query(""" + SELECT * FROM messages + WHERE account = :account + AND dialog_key = :dialogKey + AND from_public_key = :fromPublicKey + AND timestamp BETWEEN :timestampFrom AND :timestampTo + ORDER BY timestamp ASC + LIMIT 1 + """) + suspend fun findMessageByContent( + account: String, + dialogKey: String, + fromPublicKey: String, + timestampFrom: Long, + timestampTo: Long + ): MessageEntity? + /** * Получить количество непрочитанных сообщений для диалога * Считает только входящие сообщения (from_me = 0) которые не прочитаны (read = 0) diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt index 758a780..9d5efbd 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatDetailScreen.kt @@ -445,8 +445,15 @@ fun ChatDetailScreen( // 🔥 Функция для скролла к сообщению с подсветкой val scrollToMessage: (String) -> Unit = { messageId -> - android.util.Log.d("ChatDetail", "🔍 scrollToMessage called for: $messageId") + android.util.Log.d("ChatDetail", "🔍 scrollToMessage called for: '$messageId'") + android.util.Log.d("ChatDetail", " - messageId length: ${messageId.length}") android.util.Log.d("ChatDetail", " - Total messages: ${messagesWithDates.size}") + + // Логируем все ID сообщений для отладки + messagesWithDates.forEachIndexed { index, pair -> + android.util.Log.d("ChatDetail", " - [$index] id='${pair.first.id}', text='${pair.first.text.take(20)}...'") + } + scope.launch { // 🔥 Сбрасываем текущую подсветку перед новым скроллом highlightedMessageId = null diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatViewModel.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatViewModel.kt index 0562664..ac362ee 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/ChatViewModel.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/ChatViewModel.kt @@ -884,24 +884,45 @@ class ChatViewModel(application: Application) : AndroidViewModel(application) { val replyMessage = messagesArray.getJSONObject(0) val replyPublicKey = replyMessage.optString("publicKey", "") val replyText = replyMessage.optString("message", "") - val replyMessageId = replyMessage.optString("message_id", "") + val replyMessageIdFromJson = replyMessage.optString("message_id", "") + val replyTimestamp = replyMessage.optLong("timestamp", 0L) - android.util.Log.d("ReplyDebug", " - replyMessageId: $replyMessageId") + android.util.Log.d("ReplyDebug", " - replyMessageId from JSON: $replyMessageIdFromJson") android.util.Log.d("ReplyDebug", " - replyPublicKey: ${replyPublicKey.take(20)}...") android.util.Log.d("ReplyDebug", " - replyText: ${replyText.take(50)}") - android.util.Log.d("ReplyDebug", " - myPublicKey: ${myPublicKey?.take(20)}...") + android.util.Log.d("ReplyDebug", " - replyTimestamp: $replyTimestamp") + + // 🔥 ВАЖНО: message_id из JSON может не совпадать с messageId в Android БД! + // Пытаемся найти реальный messageId в текущих сообщениях по тексту и timestamp + val account = myPublicKey ?: return null + val dialogKey = getDialogKey(account, opponentKey ?: "") + val realMessageId = try { + // Ищем сообщение в БД по публичному ключу, тексту и timestamp (с допуском ±5 секунд) + messageDao.findMessageByContent( + account = account, + dialogKey = dialogKey, + fromPublicKey = replyPublicKey, + timestampFrom = replyTimestamp - 5000, + timestampTo = replyTimestamp + 5000 + )?.messageId ?: replyMessageIdFromJson + } catch (e: Exception) { + android.util.Log.w("ReplyDebug", " - ⚠️ Could not find real messageId, using JSON id") + replyMessageIdFromJson + } + + android.util.Log.d("ReplyDebug", " - Real messageId: $realMessageId") // Определяем, кто автор цитируемого сообщения val isReplyFromMe = replyPublicKey == myPublicKey android.util.Log.d("ReplyDebug", " - isReplyFromMe: $isReplyFromMe") val result = ReplyData( - messageId = replyMessageId, + messageId = realMessageId, senderName = if (isReplyFromMe) "You" else opponentTitle.ifEmpty { opponentUsername.ifEmpty { "User" } }, text = replyText, isFromMe = isReplyFromMe ) - android.util.Log.d("ReplyDebug", " - ✅ Created ReplyData: senderName=${result.senderName}, text=${result.text.take(30)}") + android.util.Log.d("ReplyDebug", " - ✅ Created ReplyData: senderName=${result.senderName}, messageId=${result.messageId}") android.util.Log.d("ReplyDebug", "✅ [DB LOAD] Reply data parsed successfully from DB - RETURNING") return result } else {