From c2b06e5cfdc0ee854267d9d92fb2d8b0b37cc7e6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 26 Oct 2021 14:15:11 +0200 Subject: [PATCH] Added fake event to indicate first unread message & unread message count in chat messages list --- .../chat/adapters/ChatMessagesListAdapter.kt | 61 +++++++++++++++++-- .../chat/fragments/DetailChatRoomFragment.kt | 28 +++++++-- .../chat_unread_messages_list_header.xml | 34 +++++++++++ app/src/main/res/values/strings.xml | 6 ++ 4 files changed, 121 insertions(+), 8 deletions(-) create mode 100644 app/src/main/res/layout/chat_unread_messages_list_header.xml diff --git a/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt b/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt index afc18450a..2451aff01 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatMessagesListAdapter.kt @@ -24,6 +24,7 @@ import android.content.ClipboardManager import android.content.Context import android.view.Gravity import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import android.widget.PopupWindow import androidx.databinding.DataBindingUtil @@ -43,16 +44,16 @@ import org.linphone.core.ChatMessage import org.linphone.core.ChatRoomCapabilities import org.linphone.core.Content import org.linphone.core.EventLog -import org.linphone.databinding.ChatEventListCellBinding -import org.linphone.databinding.ChatMessageListCellBinding -import org.linphone.databinding.ChatMessageLongPressMenuBindingImpl +import org.linphone.databinding.* import org.linphone.utils.AppUtils import org.linphone.utils.Event +import org.linphone.utils.HeaderAdapter class ChatMessagesListAdapter( selectionVM: ListTopBarViewModel, private val viewLifecycleOwner: LifecycleOwner -) : SelectionListAdapter(selectionVM, ChatMessageDiffCallback()) { +) : SelectionListAdapter(selectionVM, ChatMessageDiffCallback()), + HeaderAdapter { companion object { const val MAX_TIME_TO_GROUP_MESSAGES = 60 // 1 minute } @@ -97,6 +98,9 @@ class ChatMessagesListAdapter( private var contextMenuDisabled: Boolean = false + private var unreadMessagesCount: Int = 0 + private var firstUnreadMessagePosition: Int = -1 + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when (viewType) { EventLog.Type.ConferenceChatMessage.toInt() -> createChatMessageViewHolder(parent) @@ -133,10 +137,59 @@ class ChatMessagesListAdapter( return eventLog.eventLog.type.toInt() } + override fun onCurrentListChanged( + previousList: MutableList, + currentList: MutableList + ) { + // Need to wait for messages to be added before computing new first unread message position + firstUnreadMessagePosition = -1 + } + + override fun displayHeaderForPosition(position: Int): Boolean { + if (unreadMessagesCount > 0 && firstUnreadMessagePosition == -1) { + computeFirstUnreadMessagePosition() + } + return position == firstUnreadMessagePosition + } + + override fun getHeaderViewForPosition(context: Context, position: Int): View { + val binding: ChatUnreadMessagesListHeaderBinding = DataBindingUtil.inflate( + LayoutInflater.from(context), + R.layout.chat_unread_messages_list_header, null, false + ) + binding.title = AppUtils.getStringWithPlural(R.plurals.chat_room_unread_messages_event, unreadMessagesCount) + binding.executePendingBindings() + return binding.root + } + fun disableContextMenu() { contextMenuDisabled = true } + fun setUnreadMessageCount(count: Int, forceUpdate: Boolean) { + // Once list has been filled once, don't show the unread message header + // when new messages are added to the history whilst it is visible + unreadMessagesCount = if (itemCount == 0 || forceUpdate) count else 0 + firstUnreadMessagePosition = -1 + } + + private fun computeFirstUnreadMessagePosition() { + if (unreadMessagesCount > 0) { + var messageCount = 0 + for (position in itemCount - 1 downTo 0) { + val eventLog = getItem(position) + val data = eventLog.data + if (data is ChatMessageData) { + messageCount += 1 + if (messageCount == unreadMessagesCount) { + firstUnreadMessagePosition = position + break + } + } + } + } + } + inner class ChatMessageViewHolder( val binding: ChatMessageListCellBinding ) : RecyclerView.ViewHolder(binding.root) { diff --git a/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt b/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt index 39b9a6219..e0dd99620 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/fragments/DetailChatRoomFragment.kt @@ -80,7 +80,6 @@ class DetailChatRoomFragment : MasterFragment + adapter.setUnreadMessageCount(viewModel.chatRoom.unreadMessagesCount, viewModel.isUserScrollingUp.value == true) adapter.submitList(events) } ) @@ -388,7 +394,11 @@ class DetailChatRoomFragment : MasterFragment 0) { - binding.chatMessagesList.smoothScrollToPosition(adapter.itemCount - 1) + if (corePreferences.enableAnimations) { + binding.chatMessagesList.smoothScrollToPosition(adapter.itemCount - 1) + } else { + binding.chatMessagesList.scrollToPosition(adapter.itemCount - 1) + } } } diff --git a/app/src/main/res/layout/chat_unread_messages_list_header.xml b/app/src/main/res/layout/chat_unread_messages_list_header.xml new file mode 100644 index 000000000..0b41e89b5 --- /dev/null +++ b/app/src/main/res/layout/chat_unread_messages_list_header.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 63d22fca4..a3879da35 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -221,6 +221,12 @@ Message Hold button to record voice message Your media volume is low, you may want to increase it + %1$d unread message + %1$d unread messages + + @string/chat_room_unread_message + @string/chat_room_unread_messages + No recordings