Compare commits
2 Commits
0a9297c03d
...
6a1961e045
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a1961e045 | ||
|
|
8101cbbffd |
@@ -521,3 +521,12 @@
|
|||||||
- Bound chats top bar title to realtime state:
|
- Bound chats top bar title to realtime state:
|
||||||
- shows `Connecting...` while reconnect/initial connect is in progress,
|
- shows `Connecting...` while reconnect/initial connect is in progress,
|
||||||
- shows regular page title once connected.
|
- shows regular page title once connected.
|
||||||
|
|
||||||
|
### Step 84 - Chats list preview icon policy cleanup
|
||||||
|
- Updated chat last-message preview text to remove emoji prefixes.
|
||||||
|
- Switched media-type preview prefixes to plain text labels (`Photo`, `Video`, `Voice`, etc.) to match Material-icons-only UI policy.
|
||||||
|
|
||||||
|
### Step 85 - Unread counter fix for active/read chats
|
||||||
|
- Added `ChatDao.markChatRead(chatId)` to clear `unread_count` and `unread_mentions_count` in Room.
|
||||||
|
- Applied optimistic local unread reset on `markMessageRead(...)` in message repository.
|
||||||
|
- Fixed realtime unread logic: incoming messages in currently active chat no longer increment unread badge.
|
||||||
|
|||||||
@@ -139,6 +139,16 @@ interface ChatDao {
|
|||||||
)
|
)
|
||||||
suspend fun incrementUnread(chatId: Long, incrementBy: Int = 1)
|
suspend fun incrementUnread(chatId: Long, incrementBy: Int = 1)
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
"""
|
||||||
|
UPDATE chats
|
||||||
|
SET unread_count = 0,
|
||||||
|
unread_mentions_count = 0
|
||||||
|
WHERE id = :chatId
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
suspend fun markChatRead(chatId: Long)
|
||||||
|
|
||||||
@Transaction
|
@Transaction
|
||||||
suspend fun clearAndReplaceChats(
|
suspend fun clearAndReplaceChats(
|
||||||
archived: Boolean,
|
archived: Boolean,
|
||||||
|
|||||||
@@ -401,6 +401,8 @@ class NetworkMessageRepository @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun markMessageRead(chatId: Long, messageId: Long): AppResult<Unit> = withContext(ioDispatcher) {
|
override suspend fun markMessageRead(chatId: Long, messageId: Long): AppResult<Unit> = withContext(ioDispatcher) {
|
||||||
|
// User already viewed this chat/message in UI, so unread badge should drop immediately.
|
||||||
|
chatDao.markChatRead(chatId)
|
||||||
try {
|
try {
|
||||||
messageApiService.updateMessageStatus(
|
messageApiService.updateMessageStatus(
|
||||||
request = MessageStatusUpdateRequestDto(
|
request = MessageStatusUpdateRequestDto(
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class HandleRealtimeEventsUseCase @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is RealtimeEvent.ReceiveMessage -> {
|
is RealtimeEvent.ReceiveMessage -> {
|
||||||
|
val activeChatId = activeChatTracker.activeChatId.value
|
||||||
messageDao.upsertMessages(
|
messageDao.upsertMessages(
|
||||||
listOf(
|
listOf(
|
||||||
MessageEntity(
|
MessageEntity(
|
||||||
@@ -75,8 +76,11 @@ class HandleRealtimeEventsUseCase @Inject constructor(
|
|||||||
lastMessageCreatedAt = event.createdAt,
|
lastMessageCreatedAt = event.createdAt,
|
||||||
updatedSortAt = event.createdAt,
|
updatedSortAt = event.createdAt,
|
||||||
)
|
)
|
||||||
chatDao.incrementUnread(chatId = event.chatId)
|
if (activeChatId == event.chatId) {
|
||||||
val activeChatId = activeChatTracker.activeChatId.value
|
chatDao.markChatRead(chatId = event.chatId)
|
||||||
|
} else {
|
||||||
|
chatDao.incrementUnread(chatId = event.chatId)
|
||||||
|
}
|
||||||
val muted = chatDao.isChatMuted(event.chatId) == true
|
val muted = chatDao.isChatMuted(event.chatId) == true
|
||||||
val shouldNotify = shouldShowMessageNotificationUseCase(
|
val shouldNotify = shouldShowMessageNotificationUseCase(
|
||||||
chatId = event.chatId,
|
chatId = event.chatId,
|
||||||
|
|||||||
@@ -716,22 +716,22 @@ private fun CenterState(
|
|||||||
private fun ChatItem.previewText(): String {
|
private fun ChatItem.previewText(): String {
|
||||||
val raw = lastMessageText.orEmpty().trim()
|
val raw = lastMessageText.orEmpty().trim()
|
||||||
val prefix = when (lastMessageType) {
|
val prefix = when (lastMessageType) {
|
||||||
"image" -> "\uD83D\uDDBC"
|
"image" -> "Photo"
|
||||||
"video" -> "\uD83C\uDFA5"
|
"video" -> "Video"
|
||||||
"audio" -> "\uD83C\uDFB5"
|
"audio" -> "Audio"
|
||||||
"voice" -> "\uD83C\uDFA4"
|
"voice" -> "Voice"
|
||||||
"file" -> "\uD83D\uDCCE"
|
"file" -> "File"
|
||||||
"circle_video" -> "\u25EF"
|
"circle_video" -> "Video message"
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
if (raw.isNotEmpty()) return if (prefix.isBlank()) raw else "$prefix $raw"
|
if (raw.isNotEmpty()) return if (prefix.isBlank()) raw else "$prefix: $raw"
|
||||||
return when (lastMessageType) {
|
return when (lastMessageType) {
|
||||||
"image" -> "\uD83D\uDDBC Photo"
|
"image" -> "Photo"
|
||||||
"video" -> "\uD83C\uDFA5 Video"
|
"video" -> "Video"
|
||||||
"audio" -> "\uD83C\uDFB5 Audio"
|
"audio" -> "Audio"
|
||||||
"voice" -> "\uD83C\uDFA4 Voice message"
|
"voice" -> "Voice message"
|
||||||
"file" -> "\uD83D\uDCCE File"
|
"file" -> "File"
|
||||||
"circle_video" -> "\u25EF Video message"
|
"circle_video" -> "Video message"
|
||||||
null, "text" -> ""
|
null, "text" -> ""
|
||||||
else -> "Media"
|
else -> "Media"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user