From 9070b77b30a1738c9d7646fad235d64b7264f069 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 29 Nov 2023 09:11:13 +0100 Subject: [PATCH] Updated previous & next messages bubbles if needed when a message is deleted --- .../chat/adapter/ConversationEventAdapter.kt | 4 +- .../ui/main/chat/model/EventLogModel.kt | 10 +- .../ui/main/chat/model/MessageModel.kt | 10 +- .../chat/viewmodel/ConversationViewModel.kt | 102 +++++++++++++----- .../main/res/layout/chat_bubble_incoming.xml | 14 +-- .../main/res/layout/chat_bubble_outgoing.xml | 8 +- 6 files changed, 101 insertions(+), 47 deletions(-) diff --git a/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationEventAdapter.kt b/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationEventAdapter.kt index 1ace2ced1..dc6d52b04 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationEventAdapter.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/adapter/ConversationEventAdapter.kt @@ -210,8 +210,8 @@ class ConversationEventAdapter : ListAdapter Unit)? = null, - onJoinConferenceClicked: ((uri: String) -> Unit)? = null, - onWebUrlClicked: ((url: String) -> Unit)? = null + val onContentClicked: ((file: String) -> Unit)? = null, + val onJoinConferenceClicked: ((uri: String) -> Unit)? = null, + val onWebUrlClicked: ((url: String) -> Unit)? = null ) { companion object { private const val TAG = "[Event Log Model]" diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/MessageModel.kt b/app/src/main/java/org/linphone/ui/main/chat/model/MessageModel.kt index e9ac6ea75..ff2cb199e 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/model/MessageModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/model/MessageModel.kt @@ -66,8 +66,8 @@ class MessageModel @WorkerThread constructor( val replyTo: String, val replyText: String, val replyToMessageId: String?, - val isGroupedWithPreviousOne: Boolean, - val isGroupedWithNextOne: Boolean, + isGroupedWithPreviousOne: Boolean, + isGroupedWithNextOne: Boolean, private val onContentClicked: ((file: String) -> Unit)? = null, private val onJoinConferenceClicked: ((uri: String) -> Unit)? = null, private val onWebUrlClicked: ((url: String) -> Unit)? = null @@ -96,6 +96,10 @@ class MessageModel @WorkerThread constructor( val chatRoomIsReadOnly = chatMessage.chatRoom.isReadOnly + val groupedWithNextMessage = MutableLiveData() + + val groupedWithPreviousMessage = MutableLiveData() + val reactions = MutableLiveData() val filesList = MutableLiveData>() @@ -211,6 +215,8 @@ class MessageModel @WorkerThread constructor( } init { + groupedWithNextMessage.postValue(isGroupedWithNextOne) + groupedWithPreviousMessage.postValue(isGroupedWithPreviousOne) isPlayingVoiceRecord.postValue(false) chatMessage.addListener(chatMessageListener) diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt index 575e53af5..e5b605762 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationViewModel.kt @@ -103,22 +103,27 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { val list = arrayListOf() list.addAll(events.value.orEmpty()) + + val newList = getEventsListFromHistory( + arrayOf(eventLog), + searchFilter.value.orEmpty().trim() + ) + val lastEvent = events.value.orEmpty().lastOrNull() - if (lastEvent != null && shouldWeGroupTwoEvents(eventLog, lastEvent.eventLog)) { - list.remove(lastEvent) - val eventsLogsArray = arrayOf(lastEvent.eventLog, eventLog) - val newList = getEventsListFromHistory( - eventsLogsArray, - searchFilter.value.orEmpty().trim() + val newEvent = newList.lastOrNull() + if (lastEvent != null && newEvent != null && shouldWeGroupTwoEvents( + newEvent.eventLog, + lastEvent.eventLog ) - list.addAll(newList) - } else { - val newList = getEventsListFromHistory( - arrayOf(eventLog), - searchFilter.value.orEmpty().trim() - ) - list.addAll(newList) + ) { + if (lastEvent.model is MessageModel) { + lastEvent.model.groupedWithNextMessage.postValue(true) + } + if (newEvent.model is MessageModel) { + newEvent.model.groupedWithPreviousMessage.postValue(true) + } } + list.addAll(newList) events.postValue(list) } @@ -150,23 +155,25 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { list.addAll(events.value.orEmpty()) val lastEvent = list.lastOrNull() - if (lastEvent != null && shouldWeGroupTwoEvents(eventLogs.first(), lastEvent.eventLog)) { - list.remove(lastEvent) - val firstElement = arrayOf(lastEvent.eventLog) - val eventsLogsArray = firstElement.plus(eventLogs) - val newList = getEventsListFromHistory( - eventsLogsArray, - searchFilter.value.orEmpty().trim() + val newList = getEventsListFromHistory( + eventLogs, + searchFilter.value.orEmpty().trim() + ) + val newEvent = newList.firstOrNull() + if (lastEvent != null && newEvent != null && shouldWeGroupTwoEvents( + newEvent.eventLog, + lastEvent.eventLog ) - list.addAll(newList) - } else { - val newList = getEventsListFromHistory( - eventLogs, - searchFilter.value.orEmpty().trim() - ) - list.addAll(newList) + ) { + if (lastEvent.model is MessageModel) { + lastEvent.model.groupedWithNextMessage.postValue(true) + } + if (newEvent.model is MessageModel) { + newEvent.model.groupedWithPreviousMessage.postValue(true) + } } + list.addAll(newList) events.postValue(list) chatRoom.markAsRead() } @@ -197,8 +204,13 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { if (found != null) { val list = arrayListOf() list.addAll(eventsLogs) + + // Update previous & next messages if needed + updatePreviousAndNextMessages(list, found) + list.remove(found) events.postValue(list) + Log.i("$TAG Message was removed from events list") } else { Log.w("$TAG Failed to find matching message in events list") @@ -320,6 +332,10 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { if (found != null) { val list = arrayListOf() list.addAll(eventsLogs) + + // Update previous & next messages if needed + updatePreviousAndNextMessages(list, found) + list.remove(found) events.postValue(list) } @@ -489,6 +505,38 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { } } + @WorkerThread + private fun updatePreviousAndNextMessages(list: ArrayList, found: EventLogModel) { + val index = list.indexOf(found) + if (found.model is MessageModel) { + val messageModel = found.model + if (messageModel.groupedWithNextMessage.value == true && messageModel.groupedWithPreviousMessage.value == true) { + Log.i( + "$TAG Deleted message was grouped with both next and previous one; nothing to do" + ) + // Nothing to do + } else if (messageModel.groupedWithPreviousMessage.value == true) { + Log.i("$TAG Deleted message was grouped with previous one") + if (index > 0) { + val previous = list[index - 1] + if (previous.model is MessageModel) { + previous.model.groupedWithNextMessage.postValue(false) + Log.i("$TAG Previous message at [${index - 1}] was updated") + } + } + } else if (messageModel.groupedWithNextMessage.value == true) { + Log.i("$TAG Deleted message was grouped with next one") + if (index < list.size - 1) { + val next = list[index + 1] + if (next.model is MessageModel) { + next.model.groupedWithPreviousMessage.postValue(false) + Log.i("$TAG Next message at [${index + 1}] was updated") + } + } + } + } + } + @WorkerThread private fun computeComposingLabel() { val composingFriends = arrayListOf() diff --git a/app/src/main/res/layout/chat_bubble_incoming.xml b/app/src/main/res/layout/chat_bubble_incoming.xml index 8dd823110..d1777203e 100644 --- a/app/src/main/res/layout/chat_bubble_incoming.xml +++ b/app/src/main/res/layout/chat_bubble_incoming.xml @@ -31,14 +31,14 @@ android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginEnd="32dp" - android:layout_marginTop="@{model.isGroupedWithPreviousOne ? @dimen/chat_bubble_grouped_top_margin : @dimen/chat_bubble_top_margin, default=@dimen/chat_bubble_top_margin}"> + android:layout_marginTop="@{model.groupedWithPreviousMessage ? @dimen/chat_bubble_grouped_top_margin : @dimen/chat_bubble_top_margin, default=@dimen/chat_bubble_top_margin}"> @@ -50,7 +50,7 @@ android:layout_marginEnd="1dp" android:background="@drawable/led_background" android:padding="1dp" - android:visibility="@{model.isGroupedWithPreviousOne || !model.isFromGroup || model.avatarModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE}" + android:visibility="@{model.groupedWithPreviousMessage || !model.isFromGroup || model.avatarModel.presenceStatus == ConsolidatedPresence.Offline ? View.GONE : View.VISIBLE}" app:presenceIcon="@{model.avatarModel.presenceStatus}" app:layout_constraintEnd_toEndOf="@id/avatar" app:layout_constraintBottom_toBottomOf="@id/avatar"/> @@ -65,7 +65,7 @@ android:textColor="@color/gray_main2_700" android:maxLines="1" android:ellipsize="end" - android:visibility="@{!model.isFromGroup ? View.GONE: model.isGroupedWithPreviousOne ? View.GONE : View.VISIBLE}" + android:visibility="@{!model.isFromGroup ? View.GONE: model.groupedWithPreviousMessage ? View.GONE : View.VISIBLE}" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/reply_icon" app:layout_constraintStart_toStartOf="@id/bubble" /> @@ -139,7 +139,7 @@ android:padding="10dp" android:orientation="vertical" android:selected="@{model.isSelected}" - android:background="@{model.isGroupedWithPreviousOne ? @drawable/chat_bubble_incoming_full_background : @drawable/chat_bubble_incoming_first_background, default=@drawable/chat_bubble_incoming_first_background}" + android:background="@{model.groupedWithPreviousMessage ? @drawable/chat_bubble_incoming_full_background : @drawable/chat_bubble_incoming_first_background, default=@drawable/chat_bubble_incoming_first_background}" app:layout_constraintHorizontal_bias="0" app:layout_constraintWidth_max="@dimen/chat_bubble_max_width" app:layout_constraintTop_toBottomOf="@id/reply" @@ -214,7 +214,7 @@ android:layout_height="wrap_content" android:text="@{model.time, default=`13:40`}" android:textSize="12sp" - android:visibility="@{!model.isGroupedWithNextOne ? View.VISIBLE : View.GONE}"/> + android:visibility="@{!model.groupedWithNextMessage ? View.VISIBLE : View.GONE}"/> diff --git a/app/src/main/res/layout/chat_bubble_outgoing.xml b/app/src/main/res/layout/chat_bubble_outgoing.xml index bb67c27cb..b2d112309 100644 --- a/app/src/main/res/layout/chat_bubble_outgoing.xml +++ b/app/src/main/res/layout/chat_bubble_outgoing.xml @@ -31,7 +31,7 @@ android:layout_height="wrap_content" android:layout_marginStart="32dp" android:layout_marginEnd="8dp" - android:layout_marginTop="@{model.isGroupedWithPreviousOne ? @dimen/chat_bubble_grouped_top_margin : @dimen/chat_bubble_top_margin, default=@dimen/chat_bubble_top_margin}"> + android:layout_marginTop="@{model.groupedWithPreviousMessage ? @dimen/chat_bubble_grouped_top_margin : @dimen/chat_bubble_top_margin, default=@dimen/chat_bubble_top_margin}"> + android:visibility="@{!model.groupedWithNextMessage ? View.VISIBLE : View.GONE}"/>