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 ad4984fd1..8c83d07e4 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 @@ -119,10 +119,11 @@ class ConversationEventAdapter( with(binding) { model = chatMessageData - isGroupedWithPreviousOne = if (bindingAdapterPosition == 0) { + val position = bindingAdapterPosition + isGroupedWithPreviousOne = if (position == 0) { false } else { - val previous = bindingAdapterPosition - 1 + val previous = position - 1 if (getItemViewType(previous) == INCOMING_CHAT_MESSAGE) { val previousItem = getItem(previous).data as ChatMessageModel if (kotlin.math.abs(chatMessageData.timestamp - previousItem.timestamp) < MAX_TIME_TO_GROUP_MESSAGES) { @@ -135,10 +136,20 @@ class ConversationEventAdapter( } } - binding.setOnLongClickListener { - selectedAdapterPosition = bindingAdapterPosition - binding.root.isSelected = true + isLastOneOfGroup = if (position == itemCount - 1) { true + } else { + val next = position + 1 + if (getItemViewType(next) == INCOMING_CHAT_MESSAGE) { + val nextItem = getItem(next).data as ChatMessageModel + if (kotlin.math.abs(chatMessageData.timestamp - nextItem.timestamp) < MAX_TIME_TO_GROUP_MESSAGES) { + nextItem.fromSipUri != chatMessageData.fromSipUri + } else { + true + } + } else { + true + } } lifecycleOwner = viewLifecycleOwner @@ -154,10 +165,11 @@ class ConversationEventAdapter( with(binding) { model = chatMessageData - isGroupedWithPreviousOne = if (bindingAdapterPosition == 0) { + val position = bindingAdapterPosition + isGroupedWithPreviousOne = if (position == 0) { false } else { - val previous = bindingAdapterPosition - 1 + val previous = position - 1 if (getItemViewType(previous) == OUTGOING_CHAT_MESSAGE) { val previousItem = getItem(previous).data as ChatMessageModel if (kotlin.math.abs(chatMessageData.timestamp - previousItem.timestamp) < MAX_TIME_TO_GROUP_MESSAGES) { @@ -170,10 +182,20 @@ class ConversationEventAdapter( } } - binding.setOnLongClickListener { - selectedAdapterPosition = bindingAdapterPosition - binding.root.isSelected = true + isLastOneOfGroup = if (position == itemCount - 1) { true + } else { + val next = position + 1 + if (getItemViewType(next) == INCOMING_CHAT_MESSAGE) { + val nextItem = getItem(next).data as ChatMessageModel + if (kotlin.math.abs(chatMessageData.timestamp - nextItem.timestamp) < MAX_TIME_TO_GROUP_MESSAGES) { + nextItem.fromSipUri != chatMessageData.fromSipUri + } else { + true + } + } else { + true + } } lifecycleOwner = viewLifecycleOwner diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationsListFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationsListFragment.kt index 6b02276f7..e0fa23d80 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationsListFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationsListFragment.kt @@ -136,6 +136,7 @@ class ConversationsListFragment : AbstractTopBarFragment() { Log.i( "$TAG Default account changed, updating avatar in top bar & re-computing conversations" ) + listViewModel.applyFilter() } } diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageModel.kt b/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageModel.kt index ced04eb91..25fda053b 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/model/ChatMessageModel.kt @@ -19,6 +19,7 @@ */ package org.linphone.ui.main.chat.model +import androidx.annotation.UiThread import androidx.annotation.WorkerThread import androidx.lifecycle.MutableLiveData import org.linphone.core.ChatMessage @@ -47,4 +48,13 @@ class ChatMessageModel @WorkerThread constructor( init { state.postValue(chatMessage.state) } + + @UiThread + fun onLongClick(): Boolean { + return true + } + + @UiThread + fun showDeliveryInfo() { + } } diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/EventLogModel.kt b/app/src/main/java/org/linphone/ui/main/chat/model/EventLogModel.kt index 120058f05..fe3e360d4 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/model/EventLogModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/model/EventLogModel.kt @@ -35,11 +35,4 @@ class EventLogModel @WorkerThread constructor(eventLog: EventLog, avatarModel: C } val notifyId = eventLog.notifyId - - fun destroy() { - /*when (data) { - is EventData -> data.destroy() - is ChatMessageModel -> data.destroy() - }*/ - } } 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 f994cb302..4182cf29b 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 @@ -53,6 +53,17 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { private val avatarsMap = hashMapOf() + init { + } + + override fun onCleared() { + super.onCleared() + + coreContext.postOnCoreThread { + avatarsMap.values.forEach(ContactAvatarModel::destroy) + } + } + @UiThread fun findChatRoom(localSipUri: String, remoteSipUri: String) { coreContext.postOnCoreThread { core -> @@ -105,12 +116,14 @@ class ConversationViewModel @UiThread constructor() : ViewModel() { avatarModel.postValue(getAvatarModelForAddress(address)) val eventsList = arrayListOf() + val history = chatRoom.getHistoryEvents(0) for (event in history) { val avatar = getAvatarModelForAddress(event.chatMessage?.fromAddress) val model = EventLogModel(event, avatar) eventsList.add(model) } + events.postValue(eventsList) chatRoom.markAsRead() } diff --git a/app/src/main/res/drawable/envelope_simple.xml b/app/src/main/res/drawable/envelope_simple.xml new file mode 100644 index 000000000..abf2f983f --- /dev/null +++ b/app/src/main/res/drawable/envelope_simple.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/chat_bubble_incoming.xml b/app/src/main/res/layout/chat_bubble_incoming.xml index 35d61b6b5..71af95afc 100644 --- a/app/src/main/res/layout/chat_bubble_incoming.xml +++ b/app/src/main/res/layout/chat_bubble_incoming.xml @@ -6,19 +6,20 @@ - + + @@ -58,26 +59,90 @@ android:id="@+id/background" android:layout_width="0dp" android:layout_height="0dp" + android:layout_marginStart="10dp" android:src="@{isGroupedWithPreviousOne ? @drawable/shape_chat_bubble_incoming_full : @drawable/shape_chat_bubble_incoming_first, default=@drawable/shape_chat_bubble_incoming_first}" app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toStartOf="@id/text_message" - app:layout_constraintEnd_toEndOf="@id/text_message"/> + app:layout_constraintBottom_toBottomOf="@id/bubble_bottom_barrier" + app:layout_constraintStart_toEndOf="@id/avatar" + app:layout_constraintEnd_toEndOf="@id/bubble_end_barrier"/> - + + + + + app:layout_constrainedWidth="true" + app:layout_constraintHorizontal_bias="0" + app:layout_constraintTop_toTopOf="@id/background" + app:layout_constraintStart_toStartOf="@id/background" + app:layout_constraintEnd_toStartOf="@id/text_end_anchor"/> + + + + + + + + diff --git a/app/src/main/res/layout/chat_bubble_outgoing.xml b/app/src/main/res/layout/chat_bubble_outgoing.xml index 96897fdd6..3a0ea9338 100644 --- a/app/src/main/res/layout/chat_bubble_outgoing.xml +++ b/app/src/main/res/layout/chat_bubble_outgoing.xml @@ -14,6 +14,9 @@ +