refactor: split message event handlers
This commit is contained in:
+158
@@ -0,0 +1,158 @@
|
||||
package dev.meloda.fast.messageshistory
|
||||
|
||||
import android.util.Log
|
||||
import com.conena.nanokt.collections.indexOfFirstOrNull
|
||||
import dev.meloda.fast.common.extensions.setValue
|
||||
import dev.meloda.fast.messageshistory.model.MessagesHistoryScreenState
|
||||
import dev.meloda.fast.model.LongPollParsedEvent
|
||||
import dev.meloda.fast.model.api.domain.VkMessage
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlin.math.abs
|
||||
|
||||
internal class MessagesHistoryLongPollEventHandler(
|
||||
private val screenState: MutableStateFlow<MessagesHistoryScreenState>,
|
||||
private val messages: MutableStateFlow<List<VkMessage>>,
|
||||
private val syncUiMessages: () -> Unit
|
||||
) {
|
||||
fun onNewMessage(event: LongPollParsedEvent.NewMessage) {
|
||||
val message = event.message
|
||||
|
||||
Log.d("MessagesHistoryViewModel", "handleNewMessage: $message")
|
||||
|
||||
if (message.peerId != screenState.value.convoId) return
|
||||
if (messages.value.indexOfFirstOrNull { it.id == message.id } != null) return
|
||||
|
||||
val randomIds = messages.value.map(VkMessage::randomId)
|
||||
if (message.randomId != 0L && message.randomId in randomIds) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
newMessages.add(0, message)
|
||||
|
||||
messages.setValue { newMessages }
|
||||
syncUiMessages()
|
||||
}
|
||||
|
||||
fun onMessageEdited(event: LongPollParsedEvent.MessageEdited) {
|
||||
val message = event.message
|
||||
if (message.peerId != screenState.value.convoId) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
val index = newMessages.indexOfFirstOrNull { it.id == message.id }
|
||||
if (index == null) {
|
||||
return
|
||||
}
|
||||
|
||||
newMessages[index] = message
|
||||
messages.setValue { newMessages }
|
||||
syncUiMessages()
|
||||
}
|
||||
|
||||
fun onReadIncoming(event: LongPollParsedEvent.IncomingMessageRead) {
|
||||
if (event.peerId != screenState.value.convoId) return
|
||||
|
||||
val index = messages.value.indexOfFirstOrNull { it.cmId == event.cmId }
|
||||
if (index == null) return
|
||||
|
||||
val newConvo = screenState.value.convo.copy(
|
||||
inReadCmId = event.cmId
|
||||
)
|
||||
|
||||
screenState.setValue { old ->
|
||||
old.copy(convo = newConvo)
|
||||
}
|
||||
|
||||
syncUiMessages()
|
||||
}
|
||||
|
||||
fun onReadOutgoing(event: LongPollParsedEvent.OutgoingMessageRead) {
|
||||
if (event.peerId != screenState.value.convoId) return
|
||||
|
||||
val index = messages.value.indexOfFirstOrNull { it.cmId == event.cmId }
|
||||
if (index == null) return
|
||||
|
||||
val newConvo = screenState.value.convo.copy(
|
||||
outReadCmId = event.cmId
|
||||
)
|
||||
|
||||
screenState.setValue { old ->
|
||||
old.copy(convo = newConvo)
|
||||
}
|
||||
|
||||
syncUiMessages()
|
||||
}
|
||||
|
||||
fun onMessageDeleted(event: LongPollParsedEvent.MessageDeleted) {
|
||||
if (event.peerId != screenState.value.convoId) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
val index = newMessages.indexOfFirstOrNull { it.cmId == event.cmId }
|
||||
if (index == null) return
|
||||
|
||||
newMessages.removeAt(index)
|
||||
messages.setValue { newMessages }
|
||||
syncUiMessages()
|
||||
}
|
||||
|
||||
fun onMessageRestored(event: LongPollParsedEvent.MessageRestored) {
|
||||
if (event.message.peerId != screenState.value.convoId) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
val minDate = newMessages.minOf(VkMessage::date)
|
||||
|
||||
if (event.message.date < minDate) return
|
||||
|
||||
newMessages.add(event.message)
|
||||
messages.setValue { newMessages.sorted() }
|
||||
syncUiMessages()
|
||||
}
|
||||
|
||||
fun onMessageMarkedAsImportant(event: LongPollParsedEvent.MessageMarkedAsImportant) {
|
||||
if (event.peerId != screenState.value.convoId) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
val index = newMessages.indexOfFirstOrNull { it.cmId == event.cmId }
|
||||
if (index == null) return
|
||||
|
||||
newMessages[index] = newMessages[index].copy(isImportant = event.marked)
|
||||
messages.setValue { newMessages }
|
||||
syncUiMessages()
|
||||
}
|
||||
|
||||
fun onMessageMarkedAsSpam(event: LongPollParsedEvent.MessageMarkedAsSpam) {
|
||||
if (event.peerId != screenState.value.convoId) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
val index = newMessages.indexOfFirstOrNull { it.cmId == event.cmId }
|
||||
if (index == null) return
|
||||
|
||||
newMessages.removeAt(index)
|
||||
messages.setValue { newMessages }
|
||||
syncUiMessages()
|
||||
}
|
||||
|
||||
fun onMessageMarkedAsNotSpam(event: LongPollParsedEvent.MessageMarkedAsNotSpam) {
|
||||
if (event.message.peerId != screenState.value.convoId) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
val maxDate = newMessages.maxOf(VkMessage::date)
|
||||
val minDate = newMessages.minOf(VkMessage::date)
|
||||
|
||||
if (event.message.date !in minDate..maxDate) return
|
||||
|
||||
newMessages.add(event.message)
|
||||
messages.setValue { newMessages.sorted() }
|
||||
syncUiMessages()
|
||||
}
|
||||
|
||||
private fun List<VkMessage>.sorted(): List<VkMessage> {
|
||||
return sortedWith { m1, m2 ->
|
||||
val dateDiff = m2.date - m1.date
|
||||
if (dateDiff != 0) {
|
||||
dateDiff
|
||||
} else {
|
||||
val idDiff = m2.id - m1.id
|
||||
idDiff.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-162
@@ -58,7 +58,6 @@ import dev.meloda.fast.messageshistory.model.MessageOption
|
||||
import dev.meloda.fast.messageshistory.model.MessagesHistoryScreenState
|
||||
import dev.meloda.fast.messageshistory.navigation.MessagesHistory
|
||||
import dev.meloda.fast.model.BaseError
|
||||
import dev.meloda.fast.model.LongPollParsedEvent
|
||||
import dev.meloda.fast.model.api.domain.FormatDataType
|
||||
import dev.meloda.fast.model.api.domain.VkMessage
|
||||
import dev.meloda.fast.model.api.domain.VkPhotoDomain
|
||||
@@ -120,6 +119,13 @@ class MessagesHistoryViewModelImpl(
|
||||
|
||||
private var editMessage: VkMessage? = null
|
||||
|
||||
private val longPollEventHandler = MessagesHistoryLongPollEventHandler(
|
||||
screenState = screenState,
|
||||
messages = messages
|
||||
) {
|
||||
syncUiMessages()
|
||||
}
|
||||
|
||||
init {
|
||||
val arguments = MessagesHistory.from(savedStateHandle).arguments
|
||||
|
||||
@@ -128,15 +134,15 @@ class MessagesHistoryViewModelImpl(
|
||||
loadConvo()
|
||||
loadMessagesHistory()
|
||||
|
||||
updatesParser.onNewMessage(::handleNewMessage)
|
||||
updatesParser.onMessageEdited(::handleEditedMessage)
|
||||
updatesParser.onMessageIncomingRead(::handleReadIncomingEvent)
|
||||
updatesParser.onMessageOutgoingRead(::handleReadOutgoingEvent)
|
||||
updatesParser.onMessageDeleted(::handleMessageDeleted)
|
||||
updatesParser.onMessageRestored(::handleMessageRestored)
|
||||
updatesParser.onMessageMarkedAsImportant(::handleMessageMarkedAsImportant)
|
||||
updatesParser.onMessageMarkedAsSpam(::handleMessageMarkedAsSpam)
|
||||
updatesParser.onMessageMarkedAsNotSpam(::handleMessageMarkedAsNotSpam)
|
||||
updatesParser.onNewMessage(longPollEventHandler::onNewMessage)
|
||||
updatesParser.onMessageEdited(longPollEventHandler::onMessageEdited)
|
||||
updatesParser.onMessageIncomingRead(longPollEventHandler::onReadIncoming)
|
||||
updatesParser.onMessageOutgoingRead(longPollEventHandler::onReadOutgoing)
|
||||
updatesParser.onMessageDeleted(longPollEventHandler::onMessageDeleted)
|
||||
updatesParser.onMessageRestored(longPollEventHandler::onMessageRestored)
|
||||
updatesParser.onMessageMarkedAsImportant(longPollEventHandler::onMessageMarkedAsImportant)
|
||||
updatesParser.onMessageMarkedAsSpam(longPollEventHandler::onMessageMarkedAsSpam)
|
||||
updatesParser.onMessageMarkedAsNotSpam(longPollEventHandler::onMessageMarkedAsNotSpam)
|
||||
}
|
||||
|
||||
override fun onNavigationConsumed() {
|
||||
@@ -685,158 +691,6 @@ class MessagesHistoryViewModelImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleNewMessage(event: LongPollParsedEvent.NewMessage) {
|
||||
val message = event.message
|
||||
|
||||
Log.d("MessagesHistoryViewModel", "handleNewMessage: $message")
|
||||
|
||||
if (message.peerId != screenState.value.convoId) return
|
||||
if (messages.value.indexOfFirstOrNull { it.id == message.id } != null) return
|
||||
|
||||
val randomIds = messages.value.map(VkMessage::randomId)
|
||||
if (message.randomId != 0L && message.randomId in randomIds) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
newMessages.add(0, message)
|
||||
|
||||
messages.setValue { newMessages }
|
||||
|
||||
syncUiMessages()
|
||||
}
|
||||
|
||||
private fun handleEditedMessage(event: LongPollParsedEvent.MessageEdited) {
|
||||
val message = event.message
|
||||
if (message.peerId != screenState.value.convoId) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
val index = newMessages.indexOfFirstOrNull { it.id == message.id }
|
||||
if (index == null) { // сообщения нет в списке
|
||||
// pizdets
|
||||
} else {
|
||||
newMessages[index] = message
|
||||
messages.setValue { newMessages }
|
||||
syncUiMessages()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleReadIncomingEvent(event: LongPollParsedEvent.IncomingMessageRead) {
|
||||
if (event.peerId != screenState.value.convoId) return
|
||||
|
||||
val messages = messages.value
|
||||
val index = messages.indexOfFirstOrNull { it.cmId == event.cmId }
|
||||
|
||||
if (index == null) { // диалога нет в списке
|
||||
// pizdets
|
||||
} else {
|
||||
val newConvo = screenState.value.convo.copy(
|
||||
inReadCmId = event.cmId
|
||||
)
|
||||
|
||||
screenState.setValue { old ->
|
||||
old.copy(convo = newConvo)
|
||||
}
|
||||
|
||||
syncUiMessages()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleReadOutgoingEvent(event: LongPollParsedEvent.OutgoingMessageRead) {
|
||||
if (event.peerId != screenState.value.convoId) return
|
||||
|
||||
val messages = messages.value
|
||||
val index = messages.indexOfFirstOrNull { it.cmId == event.cmId }
|
||||
|
||||
if (index == null) { // сообщения нет в списке
|
||||
// pizdets
|
||||
} else {
|
||||
val newConvo = screenState.value.convo.copy(
|
||||
outReadCmId = event.cmId
|
||||
)
|
||||
|
||||
screenState.setValue { old ->
|
||||
old.copy(convo = newConvo)
|
||||
}
|
||||
|
||||
syncUiMessages()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleMessageDeleted(event: LongPollParsedEvent.MessageDeleted) {
|
||||
if (event.peerId != screenState.value.convoId) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
val index = newMessages.indexOfFirstOrNull { it.cmId == event.cmId }
|
||||
|
||||
if (index == null) { // сообщения нет в списке
|
||||
// pizdets
|
||||
} else {
|
||||
newMessages.removeAt(index)
|
||||
messages.setValue { newMessages }
|
||||
syncUiMessages()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleMessageRestored(event: LongPollParsedEvent.MessageRestored) {
|
||||
if (event.message.peerId != screenState.value.convoId) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
val minDate = newMessages.minOf(VkMessage::date)
|
||||
|
||||
if (event.message.date < minDate) { // сообщения не должно быть в списке
|
||||
// pizdets
|
||||
return
|
||||
}
|
||||
|
||||
newMessages.add(event.message)
|
||||
messages.setValue { newMessages.sorted() }
|
||||
syncUiMessages()
|
||||
}
|
||||
|
||||
private fun handleMessageMarkedAsImportant(event: LongPollParsedEvent.MessageMarkedAsImportant) {
|
||||
if (event.peerId != screenState.value.convoId) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
val index = newMessages.indexOfFirstOrNull { it.cmId == event.cmId }
|
||||
|
||||
if (index == null) { // сообщения нет в списке
|
||||
// pizdets
|
||||
} else {
|
||||
val newMessage = newMessages[index].copy(isImportant = event.marked)
|
||||
newMessages[index] = newMessage
|
||||
messages.setValue { newMessages }
|
||||
syncUiMessages()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleMessageMarkedAsSpam(event: LongPollParsedEvent.MessageMarkedAsSpam) {
|
||||
if (event.peerId != screenState.value.convoId) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
val index = newMessages.indexOfFirstOrNull { it.cmId == event.cmId }
|
||||
|
||||
if (index == null) { // сообщения нет в списке
|
||||
// pizdets
|
||||
} else {
|
||||
newMessages.removeAt(index)
|
||||
messages.setValue { newMessages }
|
||||
syncUiMessages()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleMessageMarkedAsNotSpam(event: LongPollParsedEvent.MessageMarkedAsNotSpam) {
|
||||
if (event.message.peerId != screenState.value.convoId) return
|
||||
|
||||
val newMessages = messages.value.toMutableList()
|
||||
val maxDate = newMessages.maxOf(VkMessage::date)
|
||||
val minDate = newMessages.minOf(VkMessage::date)
|
||||
|
||||
if (event.message.date !in minDate..maxDate) return
|
||||
|
||||
newMessages.add(event.message)
|
||||
messages.setValue { newMessages.sorted() }
|
||||
syncUiMessages()
|
||||
}
|
||||
|
||||
private fun loadConvo() {
|
||||
Log.d("MessagesHistoryViewModelImpl", "loadConvo()")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user