fix(android): preload message reactions on chat open
This commit is contained in:
@@ -68,6 +68,7 @@ class ChatViewModel @Inject constructor(
|
|||||||
private val visibleMessagesLimit = MutableStateFlow(MESSAGES_PAGE_SIZE)
|
private val visibleMessagesLimit = MutableStateFlow(MESSAGES_PAGE_SIZE)
|
||||||
private var lastDeliveredMessageId: Long? = null
|
private var lastDeliveredMessageId: Long? = null
|
||||||
private var lastReadMessageId: Long? = null
|
private var lastReadMessageId: Long? = null
|
||||||
|
private val reactionsRequestedMessageIds = mutableSetOf<Long>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
activeChatTracker.setActiveChat(chatId)
|
activeChatTracker.setActiveChat(chatId)
|
||||||
@@ -562,13 +563,14 @@ class ChatViewModel @Inject constructor(
|
|||||||
visibleMessagesLimit
|
visibleMessagesLimit
|
||||||
.flatMapLatest { limit -> observeMessagesUseCase(chatId = chatId, limit = limit) }
|
.flatMapLatest { limit -> observeMessagesUseCase(chatId = chatId, limit = limit) }
|
||||||
.collectLatest { messages ->
|
.collectLatest { messages ->
|
||||||
|
val sortedMessages = messages.sortedBy { msg -> msg.id }
|
||||||
_uiState.update {
|
_uiState.update {
|
||||||
val pinnedId = it.pinnedMessageId
|
val pinnedId = it.pinnedMessageId
|
||||||
val normalized = it.inlineSearchQuery.trim().lowercase()
|
val normalized = it.inlineSearchQuery.trim().lowercase()
|
||||||
val inlineMatches = if (normalized.isBlank()) {
|
val inlineMatches = if (normalized.isBlank()) {
|
||||||
emptyList()
|
emptyList()
|
||||||
} else {
|
} else {
|
||||||
messages
|
sortedMessages
|
||||||
.filter { msg -> (msg.text ?: "").lowercase().contains(normalized) }
|
.filter { msg -> (msg.text ?: "").lowercase().contains(normalized) }
|
||||||
.map { msg -> msg.id }
|
.map { msg -> msg.id }
|
||||||
}
|
}
|
||||||
@@ -579,13 +581,14 @@ class ChatViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
it.copy(
|
it.copy(
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
messages = messages.sortedBy { msg -> msg.id },
|
messages = sortedMessages,
|
||||||
pinnedMessage = pinnedId?.let { id -> messages.firstOrNull { msg -> msg.id == id } },
|
pinnedMessage = pinnedId?.let { id -> sortedMessages.firstOrNull { msg -> msg.id == id } },
|
||||||
inlineSearchMatches = inlineMatches,
|
inlineSearchMatches = inlineMatches,
|
||||||
highlightedMessageId = highlighted,
|
highlightedMessageId = highlighted,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
acknowledgeLatestMessages(messages)
|
preloadReactions(sortedMessages)
|
||||||
|
acknowledgeLatestMessages(sortedMessages)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -659,6 +662,28 @@ class ChatViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun preloadReactions(messages: List<MessageItem>) {
|
||||||
|
val toRequest = messages
|
||||||
|
.asReversed()
|
||||||
|
.map { it.id }
|
||||||
|
.filter { reactionsRequestedMessageIds.add(it) }
|
||||||
|
|
||||||
|
if (toRequest.isEmpty()) return
|
||||||
|
|
||||||
|
toRequest.forEach { messageId ->
|
||||||
|
viewModelScope.launch {
|
||||||
|
when (val result = listMessageReactionsUseCase(messageId = messageId)) {
|
||||||
|
is AppResult.Success -> {
|
||||||
|
_uiState.update {
|
||||||
|
it.copy(reactionByMessageId = it.reactionByMessageId + (messageId to result.data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is AppResult.Error -> Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun acknowledgeLatestMessages(messages: List<MessageItem>) {
|
private fun acknowledgeLatestMessages(messages: List<MessageItem>) {
|
||||||
val latestIncoming = messages.asReversed().firstOrNull { !it.isOutgoing }
|
val latestIncoming = messages.asReversed().firstOrNull { !it.isOutgoing }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user