+108
-71
@@ -23,7 +23,7 @@ import dev.meloda.fast.domain.LongPollUpdatesParser
|
||||
import dev.meloda.fast.domain.MessagesUseCase
|
||||
import dev.meloda.fast.model.BaseError
|
||||
import dev.meloda.fast.model.InteractionType
|
||||
import dev.meloda.fast.model.LongPollEvent
|
||||
import dev.meloda.fast.model.LongPollParsedEvent
|
||||
import dev.meloda.fast.model.api.domain.VkConversation
|
||||
import dev.meloda.fast.network.VkErrorCode
|
||||
import dev.meloda.fast.ui.model.api.ConversationOption
|
||||
@@ -104,8 +104,10 @@ class ConversationsViewModelImpl(
|
||||
updatesParser.onMessageEdited(::handleEditedMessage)
|
||||
updatesParser.onMessageIncomingRead(::handleReadIncomingMessage)
|
||||
updatesParser.onMessageOutgoingRead(::handleReadOutgoingMessage)
|
||||
updatesParser.onConversationPinStateChanged(::handlePinStateChanged)
|
||||
updatesParser.onInteractions(::handleInteraction)
|
||||
updatesParser.onChatMajorChanged(::handleChatMajorChanged)
|
||||
updatesParser.onChatMinorChanged(::handleChatMinorChanged)
|
||||
updatesParser.onChatCleared(::handleChatClearing)
|
||||
|
||||
loadConversations()
|
||||
}
|
||||
@@ -348,9 +350,7 @@ class ConversationsViewModelImpl(
|
||||
private fun deleteConversation(peerId: Int) {
|
||||
conversationsUseCase.delete(peerId).listenValue(viewModelScope) { state ->
|
||||
state.processState(
|
||||
error = { error ->
|
||||
|
||||
},
|
||||
error = {},
|
||||
success = {
|
||||
val newConversations = conversations.value.toMutableList()
|
||||
val conversationIndex =
|
||||
@@ -359,16 +359,7 @@ class ConversationsViewModelImpl(
|
||||
|
||||
newConversations.removeAt(conversationIndex)
|
||||
conversations.update { newConversations }
|
||||
screenState.setValue { old ->
|
||||
old.copy(
|
||||
conversations = newConversations.map {
|
||||
it.asPresentation(
|
||||
resources = resources,
|
||||
useContactName = useContactNames
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
sortConversations()
|
||||
}
|
||||
)
|
||||
screenState.emit(screenState.value.copy(isLoading = state.isLoading()))
|
||||
@@ -379,15 +370,13 @@ class ConversationsViewModelImpl(
|
||||
conversationsUseCase.changePinState(peerId, pin)
|
||||
.listenValue(viewModelScope) { state ->
|
||||
state.processState(
|
||||
error = { error ->
|
||||
|
||||
},
|
||||
error = {},
|
||||
success = {
|
||||
handlePinStateChanged(
|
||||
LongPollEvent.VkConversationPinStateChangedEvent(
|
||||
handleChatMajorChanged(
|
||||
LongPollParsedEvent.ChatMajorChanged(
|
||||
peerId = peerId,
|
||||
majorId = if (pin) {
|
||||
(pinnedConversationsCount.value + 1) * 16
|
||||
pinnedConversationsCount.value.plus(1) * 16
|
||||
} else {
|
||||
0
|
||||
}
|
||||
@@ -400,7 +389,7 @@ class ConversationsViewModelImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleNewMessage(event: LongPollEvent.VkMessageNewEvent) {
|
||||
private fun handleNewMessage(event: LongPollParsedEvent.NewMessage) {
|
||||
val message = event.message
|
||||
|
||||
val newConversations = conversations.value.toMutableList()
|
||||
@@ -411,28 +400,14 @@ class ConversationsViewModelImpl(
|
||||
loadConversationsByIdUseCase(peerIds = listOf(message.peerId))
|
||||
.listenValue(viewModelScope) { state ->
|
||||
state.processState(
|
||||
error = { error ->
|
||||
|
||||
},
|
||||
error = {},
|
||||
success = { response ->
|
||||
val conversation = (response.firstOrNull() ?: return@listenValue)
|
||||
.copy(lastMessage = message)
|
||||
|
||||
// TODO: 22-Dec-24, Danil Nikolaev: handle interactions and pinned state
|
||||
|
||||
newConversations.add(pinnedConversationsCount.value, conversation)
|
||||
conversations.update { newConversations }
|
||||
|
||||
screenState.setValue { old ->
|
||||
old.copy(
|
||||
conversations = newConversations.map {
|
||||
it.asPresentation(
|
||||
resources = resources,
|
||||
useContactName = useContactNames
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
sortConversations()
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -487,7 +462,7 @@ class ConversationsViewModelImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleEditedMessage(event: LongPollEvent.VkMessageEditEvent) {
|
||||
private fun handleEditedMessage(event: LongPollParsedEvent.MessageEdited) {
|
||||
val message = event.message
|
||||
val newConversations = conversations.value.toMutableList()
|
||||
|
||||
@@ -516,7 +491,7 @@ class ConversationsViewModelImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleReadIncomingMessage(event: LongPollEvent.VkMessageReadIncomingEvent) {
|
||||
private fun handleReadIncomingMessage(event: LongPollParsedEvent.IncomingMessageRead) {
|
||||
val newConversations = conversations.value.toMutableList()
|
||||
|
||||
val conversationIndex =
|
||||
@@ -546,7 +521,7 @@ class ConversationsViewModelImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleReadOutgoingMessage(event: LongPollEvent.VkMessageReadOutgoingEvent) {
|
||||
private fun handleReadOutgoingMessage(event: LongPollParsedEvent.OutgoingMessageRead) {
|
||||
val newConversations = conversations.value.toMutableList()
|
||||
|
||||
val conversationIndex =
|
||||
@@ -575,47 +550,113 @@ class ConversationsViewModelImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePinStateChanged(event: LongPollEvent.VkConversationPinStateChangedEvent) {
|
||||
var pinnedCount = pinnedConversationsCount.value
|
||||
private fun handleChatMajorChanged(event: LongPollParsedEvent.ChatMajorChanged) {
|
||||
val newConversations = conversations.value.toMutableList()
|
||||
|
||||
val conversationIndex =
|
||||
newConversations.indexOfFirstOrNull { it.id == event.peerId }
|
||||
|
||||
if (conversationIndex == null) { // диалога нет в списке
|
||||
// pizdets
|
||||
} else {
|
||||
val pin = event.majorId > 0
|
||||
newConversations[conversationIndex] =
|
||||
newConversations[conversationIndex].copy(majorId = event.majorId)
|
||||
|
||||
val conversation = newConversations[conversationIndex].copy(majorId = event.majorId)
|
||||
conversations.setValue { newConversations }
|
||||
screenState.setValue { old ->
|
||||
old.copy(
|
||||
conversations = newConversations.map {
|
||||
it.asPresentation(
|
||||
resources = resources,
|
||||
useContactName = useContactNames
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
sortConversations()
|
||||
}
|
||||
}
|
||||
|
||||
newConversations.removeAt(conversationIndex)
|
||||
private fun handleChatMinorChanged(event: LongPollParsedEvent.ChatMinorChanged) {
|
||||
val newConversations = conversations.value.toMutableList()
|
||||
val conversationIndex =
|
||||
newConversations.indexOfFirstOrNull { it.id == event.peerId }
|
||||
|
||||
if (pin) {
|
||||
newConversations.add(0, conversation)
|
||||
} else {
|
||||
pinnedCount -= 1
|
||||
if (conversationIndex == null) { // диалога нет в списке
|
||||
// pizdets
|
||||
} else {
|
||||
newConversations[conversationIndex] =
|
||||
newConversations[conversationIndex].copy(minorId = event.minorId)
|
||||
|
||||
newConversations.add(conversation)
|
||||
conversations.setValue { newConversations }
|
||||
screenState.setValue { old ->
|
||||
old.copy(
|
||||
conversations = newConversations.map {
|
||||
it.asPresentation(
|
||||
resources = resources,
|
||||
useContactName = useContactNames
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
sortConversations()
|
||||
}
|
||||
}
|
||||
|
||||
val pinnedSubList = newConversations.filter(VkConversation::isPinned)
|
||||
val unpinnedSubList = newConversations
|
||||
.filterNot(VkConversation::isPinned)
|
||||
.sortedByDescending { it.lastMessage?.date }
|
||||
private fun sortConversations() {
|
||||
val newConversations = conversations.value.toMutableList()
|
||||
val pinnedConversations = newConversations
|
||||
.filter(VkConversation::isPinned)
|
||||
.sortedWith { c1, c2 ->
|
||||
val diff = c2.majorId - c1.majorId
|
||||
|
||||
newConversations.clear()
|
||||
newConversations += pinnedSubList + unpinnedSubList
|
||||
if (diff == 0) {
|
||||
c2.minorId - c1.minorId
|
||||
} else {
|
||||
diff
|
||||
}
|
||||
}
|
||||
|
||||
conversations.update { newConversations }
|
||||
newConversations.removeAll(pinnedConversations)
|
||||
newConversations.sortWith { c1, c2 ->
|
||||
(c2.lastMessage?.date ?: 0) - (c1.lastMessage?.date ?: 0)
|
||||
}
|
||||
|
||||
screenState.setValue { old ->
|
||||
old.copy(conversations = newConversations.map {
|
||||
newConversations.addAll(0, pinnedConversations)
|
||||
|
||||
conversations.update { newConversations }
|
||||
screenState.setValue { old ->
|
||||
old.copy(
|
||||
conversations = newConversations.map {
|
||||
it.asPresentation(
|
||||
resources = resources,
|
||||
useContactName = useContactNames
|
||||
)
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleChatClearing(event: LongPollParsedEvent.ChatCleared) {
|
||||
val newConversations = conversations.value.toMutableList()
|
||||
|
||||
val conversationIndex = newConversations.indexOfFirstOrNull { it.id == event.peerId }
|
||||
|
||||
if (conversationIndex == null) { // диалога нет в списке
|
||||
// pizdets
|
||||
} else {
|
||||
newConversations.removeAt(conversationIndex)
|
||||
|
||||
conversations.setValue { newConversations }
|
||||
|
||||
screenState.setValue { old ->
|
||||
old.copy(
|
||||
conversations = newConversations.map {
|
||||
it.asPresentation(
|
||||
resources = resources,
|
||||
useContactName = useContactNames
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -627,9 +668,9 @@ class ConversationsViewModelImpl(
|
||||
val timerJob: Job
|
||||
)
|
||||
|
||||
private object NewInteractionException : CancellationException()
|
||||
private class NewInteractionException : CancellationException()
|
||||
|
||||
private fun handleInteraction(event: LongPollEvent.Interaction) {
|
||||
private fun handleInteraction(event: LongPollParsedEvent.Interaction) {
|
||||
val interactionType = event.interactionType
|
||||
val peerId = event.peerId
|
||||
val userIds = event.userIds
|
||||
@@ -638,9 +679,7 @@ class ConversationsViewModelImpl(
|
||||
val conversationAndIndex =
|
||||
newConversations.findWithIndex { it.id == peerId }
|
||||
|
||||
if (conversationAndIndex == null) { // диалога нет в списке
|
||||
// pizdets
|
||||
} else {
|
||||
if (conversationAndIndex != null) {
|
||||
newConversations[conversationAndIndex.first] =
|
||||
conversationAndIndex.second.copy(
|
||||
interactionType = interactionType.value,
|
||||
@@ -662,7 +701,7 @@ class ConversationsViewModelImpl(
|
||||
|
||||
interactionsTimers[peerId]?.let { interactionJob ->
|
||||
if (interactionJob.interactionType == interactionType) {
|
||||
interactionJob.timerJob.cancel(NewInteractionException)
|
||||
interactionJob.timerJob.cancel(NewInteractionException())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -721,9 +760,7 @@ class ConversationsViewModelImpl(
|
||||
startMessageId = startMessageId
|
||||
).listenValue(viewModelScope) { state ->
|
||||
state.processState(
|
||||
error = { error ->
|
||||
|
||||
},
|
||||
error = {},
|
||||
success = {
|
||||
val newConversations = conversations.value.toMutableList()
|
||||
val conversationIndex =
|
||||
|
||||
Reference in New Issue
Block a user