fix: reconcile realtime mention counters locally
Some checks failed
Android CI / android (push) Has started running
Android Release / release (push) Has been cancelled
CI / test (push) Has been cancelled

fix: update unread mention badges from websocket events

fix: clear stale notifications when active chats receive messages
This commit is contained in:
2026-04-05 15:04:01 +03:00
parent d2d3f2f08e
commit 75214737b9
2 changed files with 26 additions and 17 deletions

View File

@@ -136,11 +136,15 @@ interface ChatDao {
SET unread_count = CASE
WHEN :incrementBy > 0 THEN unread_count + :incrementBy
ELSE unread_count
END,
unread_mentions_count = CASE
WHEN :mentionIncrementBy > 0 THEN unread_mentions_count + :mentionIncrementBy
ELSE unread_mentions_count
END
WHERE id = :chatId
"""
)
suspend fun incrementUnread(chatId: Long, incrementBy: Int = 1)
suspend fun incrementUnread(chatId: Long, incrementBy: Int = 1, mentionIncrementBy: Int = 0)
@Query(
"""

View File

@@ -54,6 +54,21 @@ class HandleRealtimeEventsUseCase @Inject constructor(
val activeChatId = activeChatTracker.activeChatId.value
val activeUserId = tokenRepository.getActiveUserId()
val isOwnMessage = activeUserId != null && event.senderId == activeUserId
val myUsername = activeUserId?.let { userId ->
tokenRepository.getAccounts()
.firstOrNull { it.userId == userId }
?.username
?.trim()
?.removePrefix("@")
?.lowercase()
}
val isMentionByText = if (myUsername.isNullOrBlank()) {
false
} else {
Regex("(^|\\W)@${Regex.escape(myUsername)}(\\W|$)", RegexOption.IGNORE_CASE)
.containsMatchIn(event.text.orEmpty())
}
val isMention = event.isMention || isMentionByText
val lastMessagePreview = event.text?.takeIf { it.isNotBlank() }
?: fallbackMessagePreview(event.type)
messageDao.upsertMessages(
@@ -89,25 +104,15 @@ class HandleRealtimeEventsUseCase @Inject constructor(
if (activeChatId == event.chatId) {
chatDao.markChatRead(chatId = event.chatId)
messageRepository.syncRecentMessages(chatId = event.chatId)
notificationDispatcher.clearChatNotifications(event.chatId)
} else if (!isOwnMessage) {
chatDao.incrementUnread(chatId = event.chatId)
chatDao.incrementUnread(
chatId = event.chatId,
incrementBy = 1,
mentionIncrementBy = if (isMention) 1 else 0,
)
}
chatRepository.refreshChat(chatId = event.chatId)
val myUsername = activeUserId?.let { userId ->
tokenRepository.getAccounts()
.firstOrNull { it.userId == userId }
?.username
?.trim()
?.removePrefix("@")
?.lowercase()
}
val isMentionByText = if (myUsername.isNullOrBlank()) {
false
} else {
Regex("(^|\\W)@${Regex.escape(myUsername)}(\\W|$)", RegexOption.IGNORE_CASE)
.containsMatchIn(event.text.orEmpty())
}
val isMention = event.isMention || isMentionByText
val muted = chatDao.isChatMuted(event.chatId) == true
val shouldNotify = shouldShowMessageNotificationUseCase(
chatId = event.chatId,