diff --git a/android/CHANGELOG.md b/android/CHANGELOG.md index f9f68e3..eaaaceb 100644 --- a/android/CHANGELOG.md +++ b/android/CHANGELOG.md @@ -700,3 +700,9 @@ - unregister token on logout, - handle foreground push payload via existing notification service worker. - Added required env keys to `web/.env.example` and backend Firebase env keys to root `.env.example`. + +### Step 106 - Unread counter stabilization in Chat screen +- Fixed read acknowledgement strategy in `ChatViewModel`: + - read status is now acknowledged by the latest visible message id in chat (not only latest incoming), + - delivery status still uses latest incoming message. +- This removes cases where unread badge reappears after chat list refresh because the previous read ack used an outdated incoming id. diff --git a/android/app/src/main/java/ru/daemonlord/messenger/ui/chat/ChatViewModel.kt b/android/app/src/main/java/ru/daemonlord/messenger/ui/chat/ChatViewModel.kt index 367b547..3da6006 100644 --- a/android/app/src/main/java/ru/daemonlord/messenger/ui/chat/ChatViewModel.kt +++ b/android/app/src/main/java/ru/daemonlord/messenger/ui/chat/ChatViewModel.kt @@ -571,7 +571,7 @@ class ChatViewModel @Inject constructor( highlightedMessageId = highlighted, ) } - acknowledgeLatestIncoming(messages) + acknowledgeLatestMessages(messages) } } } @@ -644,22 +644,20 @@ class ChatViewModel @Inject constructor( } } - private fun acknowledgeLatestIncoming(messages: List) { - val latestIncoming = messages - .asReversed() - .firstOrNull { !it.isOutgoing } - ?: return + private fun acknowledgeLatestMessages(messages: List) { + val latestVisible = messages.maxByOrNull { it.id } ?: return + val latestIncoming = messages.asReversed().firstOrNull { !it.isOutgoing } - if (lastDeliveredMessageId != latestIncoming.id) { + if (latestIncoming != null && lastDeliveredMessageId != latestIncoming.id) { lastDeliveredMessageId = latestIncoming.id viewModelScope.launch { markMessageDeliveredUseCase(chatId = chatId, messageId = latestIncoming.id) } } - if (lastReadMessageId != latestIncoming.id) { - lastReadMessageId = latestIncoming.id + if (lastReadMessageId != latestVisible.id) { + lastReadMessageId = latestVisible.id viewModelScope.launch { - markMessageReadUseCase(chatId = chatId, messageId = latestIncoming.id) + markMessageReadUseCase(chatId = chatId, messageId = latestVisible.id) } } }