Improved a few things related to conversation

This commit is contained in:
Sylvain Berfini 2024-03-28 10:54:23 +01:00
parent 8a2e2c074b
commit 7076acc540
3 changed files with 49 additions and 34 deletions

View file

@ -185,7 +185,10 @@ class ConversationFragment : SlidingPaneChildFragment() {
private val dataObserver = object : AdapterDataObserver() {
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
if (positionStart == adapter.itemCount - itemCount) {
if (positionStart > 0 && positionStart == adapter.itemCount - itemCount) {
Log.i(
"$TAG Item(s) inserted at the end, notify item changed at position [${positionStart - 1}]"
)
adapter.notifyItemChanged(positionStart - 1) // For grouping purposes
}
@ -399,11 +402,10 @@ class ConversationFragment : SlidingPaneChildFragment() {
}
}
viewModel.events.observe(viewLifecycleOwner) { items ->
if (items != adapter.currentList || items.size != adapter.itemCount) {
adapter.submitList(items)
Log.i("$TAG Events (messages) list updated with [${items.size}] items")
}
viewModel.updateEvents.observe(viewLifecycleOwner) {
val items = viewModel.eventsList
adapter.submitList(items)
Log.i("$TAG Events (messages) list updated, contains [${items.size}] items")
(view.parent as? ViewGroup)?.doOnPreDraw {
sharedViewModel.openSlidingPaneEvent.value = Event(true)
@ -720,9 +722,11 @@ class ConversationFragment : SlidingPaneChildFragment() {
@UiThread
override fun onScrolledToEnd() {
viewModel.isUserScrollingUp.value = false
Log.i("$TAG Last message is visible, considering conversation as read")
viewModel.markAsRead()
if (viewModel.isUserScrollingUp.value == true) {
viewModel.isUserScrollingUp.value = false
Log.i("$TAG Last message is visible, considering conversation as read")
viewModel.markAsRead()
}
}
}
binding.eventsList.addOnScrollListener(scrollListener)

View file

@ -59,7 +59,7 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
val avatarModel = MutableLiveData<ContactAvatarModel>()
val events = MutableLiveData<ArrayList<EventLogModel>>()
val isEmpty = MutableLiveData<Boolean>()
val isMuted = MutableLiveData<Boolean>()
@ -117,7 +117,11 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
MutableLiveData<Event<Boolean>>()
}
private var eventsList = arrayListOf<EventLogModel>()
val updateEvents: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
var eventsList = arrayListOf<EventLogModel>()
private val chatRoomListener = object : ChatRoomListenerStub() {
@WorkerThread
@ -255,7 +259,8 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
Log.i("$TAG Removing message from conversation events list")
list.remove(found)
eventsList = list
events.postValue(eventsList)
updateEvents.postValue(Event(true))
isEmpty.postValue(eventsList.isEmpty())
} else {
Log.e("$TAG Failed to find matching message in conversation events list")
}
@ -363,7 +368,8 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
Log.i("$TAG Removing chat message id [${chatMessageModel.id}] from events list")
list.remove(found)
eventsList = list
events.postValue(eventsList)
updateEvents.postValue(Event(true))
isEmpty.postValue(eventsList.isEmpty())
} else {
Log.e(
"$TAG Failed to find chat message id [${chatMessageModel.id}] in events list!"
@ -454,23 +460,20 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
val lastEvent = list.lastOrNull()
val newEvent = eventsList.firstOrNull()
if (lastEvent != null && newEvent != null && shouldWeGroupTwoEvents(
if (lastEvent != null && lastEvent.model is MessageModel && newEvent != null && newEvent.model is MessageModel && shouldWeGroupTwoEvents(
newEvent.eventLog,
lastEvent.eventLog
)
) {
if (lastEvent.model is MessageModel) {
lastEvent.model.groupedWithNextMessage.postValue(true)
}
if (newEvent.model is MessageModel) {
newEvent.model.groupedWithPreviousMessage.postValue(true)
}
lastEvent.model.groupedWithNextMessage.postValue(true)
newEvent.model.groupedWithPreviousMessage.postValue(true)
}
Log.i("$TAG More data loaded, adding it to conversation events list")
list.addAll(eventsList)
eventsList = list
events.postValue(eventsList)
updateEvents.postValue(Event(true))
isEmpty.postValue(eventsList.isEmpty())
}
}
}
@ -498,7 +501,8 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
val group = LinphoneUtils.isChatRoomAGroup(chatRoom)
isGroup.postValue(group)
val empty = chatRoom.hasCapability(ChatRoom.Capabilities.Conference.toInt()) && chatRoom.participants.isEmpty()
val empty =
chatRoom.hasCapability(ChatRoom.Capabilities.Conference.toInt()) && chatRoom.participants.isEmpty()
val readOnly = chatRoom.isReadOnly || empty
isReadOnly.postValue(readOnly)
if (readOnly) {
@ -556,7 +560,8 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
val list = getEventsListFromHistory(history, filter)
Log.i("$TAG Extracted [${list.size}] events from conversation history in database")
eventsList = list
events.postValue(eventsList)
updateEvents.postValue(Event(true))
isEmpty.postValue(eventsList.isEmpty())
if (filter.isNotEmpty() && eventsList.isEmpty()) {
noMatchingResultForFilter.postValue(true)
@ -567,6 +572,8 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
@WorkerThread
private fun addEvents(eventLogs: Array<EventLog>) {
Log.i("$TAG Adding [${eventLogs.size}] events")
// Need to use a new list, otherwise ConversationFragment's dataObserver isn't triggered...
val list = arrayListOf<EventLogModel>()
list.addAll(eventsList)
val lastEvent = list.lastOrNull()
@ -576,22 +583,20 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
searchFilter.value.orEmpty().trim()
)
val newEvent = newList.firstOrNull()
if (lastEvent != null && newEvent != null && shouldWeGroupTwoEvents(
if (lastEvent != null && lastEvent.model is MessageModel && newEvent != null && newEvent.model is MessageModel && shouldWeGroupTwoEvents(
newEvent.eventLog,
lastEvent.eventLog
)
) {
if (lastEvent.model is MessageModel) {
lastEvent.model.groupedWithNextMessage.postValue(true)
}
if (newEvent.model is MessageModel) {
newEvent.model.groupedWithPreviousMessage.postValue(true)
}
lastEvent.model.groupedWithNextMessage.postValue(true)
newEvent.model.groupedWithPreviousMessage.postValue(true)
}
list.addAll(newList)
eventsList = list
events.postValue(eventsList)
updateEvents.postValue(Event(true))
isEmpty.postValue(eventsList.isEmpty())
}
@WorkerThread
@ -637,7 +642,10 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
}
@WorkerThread
private fun getEventsListFromHistory(history: Array<EventLog>, filter: String = ""): ArrayList<EventLogModel> {
private fun getEventsListFromHistory(
history: Array<EventLog>,
filter: String = ""
): ArrayList<EventLogModel> {
val eventsList = arrayListOf<EventLogModel>()
val groupedEventLogs = arrayListOf<EventLog>()
@ -708,7 +716,10 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
}
@WorkerThread
private fun updatePreviousAndNextMessages(list: ArrayList<EventLogModel>, found: EventLogModel) {
private fun updatePreviousAndNextMessages(
list: ArrayList<EventLogModel>,
found: EventLogModel
) {
val index = list.indexOf(found)
if (found.model is MessageModel) {
val messageModel = found.model

View file

@ -232,7 +232,7 @@
android:onClick="@{endToEndEncryptedEventClickListener}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="@{viewModel.events.size() == 0 &amp;&amp; viewModel.isEndToEndEncrypted ? View.VISIBLE : View.GONE}"
android:visibility="@{viewModel.isEmpty &amp;&amp; viewModel.isEndToEndEncrypted ? View.VISIBLE : View.GONE}"
layout="@layout/chat_conversation_secured_first_event"
app:layout_constraintTop_toTopOf="@id/events_list"
app:layout_constraintStart_toStartOf="@id/events_list"