diff --git a/app/src/main/java/chat/rocket/android/chatroom/adapter/BaseViewHolder.kt b/app/src/main/java/chat/rocket/android/chatroom/adapter/BaseViewHolder.kt index 68b420e7d5..fb792f5876 100644 --- a/app/src/main/java/chat/rocket/android/chatroom/adapter/BaseViewHolder.kt +++ b/app/src/main/java/chat/rocket/android/chatroom/adapter/BaseViewHolder.kt @@ -29,13 +29,15 @@ abstract class BaseViewHolder>( ) : RecyclerView.ViewHolder(itemView), MenuItem.OnMenuItemClickListener { var data: T? = null + var groupMessage = false init { setupActionMenu(itemView) } - fun bind(data: T) { + fun bind(data: T, groupMessage: Boolean = false) { this.data = data + this.groupMessage = groupMessage bindViews(data) bindReactions() } diff --git a/app/src/main/java/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt b/app/src/main/java/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt index d574952c00..6374693171 100644 --- a/app/src/main/java/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt +++ b/app/src/main/java/chat/rocket/android/chatroom/adapter/ChatRoomAdapter.kt @@ -1,5 +1,6 @@ package chat.rocket.android.chatroom.adapter +import android.content.res.Resources import android.view.MenuItem import android.view.View import android.view.ViewGroup @@ -25,6 +26,9 @@ import chat.rocket.core.model.attachment.actions.ButtonAction import chat.rocket.core.model.isSystemMessage import timber.log.Timber import java.security.InvalidParameterException +import java.util.Calendar +import kotlin.Comparator +import kotlin.collections.ArrayList class ChatRoomAdapter( private val roomId: String? = null, @@ -109,9 +113,24 @@ class ChatRoomAdapter( } } + var groupMessage = false + + if (position + 1 < dataSet.size) { + val a = dataSet[position].message + val b = dataSet[position + 1].message + + groupMessage = shouldGroupMessage(a, b) + + a.attachments?.let { + if (it.any { a -> a.type != null }) { // check if message media attachment. + groupMessage = false + } + } + } + when (holder) { is MessageViewHolder -> - holder.bind(dataSet[position] as MessageUiModel) + holder.bind(dataSet[position] as MessageUiModel, groupMessage) is UrlPreviewViewHolder -> { holder.bind(dataSet[position] as UrlPreviewUiModel) } @@ -122,6 +141,19 @@ class ChatRoomAdapter( } } + + private fun shouldGroupMessage(a: Message, b: Message): Boolean { + if (a.senderAlias == b.senderAlias) { + val date1 = a.getDate() + val date2 = b.getDate() + + if (date1.isSameDay(date2) && date1.timeInMillis - date2.timeInMillis <= 900000) // this should be depend on settings. + return true + } + + return false + } + override fun getItemId(position: Int): Long { val model = dataSet[position] return when (model) { @@ -373,3 +405,18 @@ class ChatRoomAdapter( fun openConfigurableWebPage(roomId: String, url: String, heightRatio: String) } } + +fun Message.getDate(): Calendar { + return Calendar.getInstance().apply { + timeInMillis = this@getDate.timestamp + } +} + +fun Calendar.isSameDay(other: Calendar): Boolean { + return this.get(Calendar.YEAR) == other.get(Calendar.YEAR) && + this.get(Calendar.MONTH) == other.get(Calendar.MONTH) && + this.get(Calendar.DAY_OF_MONTH) == other.get(Calendar.DAY_OF_MONTH) +} + +val Int.toPx: Float + get() = (this * Resources.getSystem().displayMetrics.density) diff --git a/app/src/main/java/chat/rocket/android/chatroom/adapter/MessageViewHolder.kt b/app/src/main/java/chat/rocket/android/chatroom/adapter/MessageViewHolder.kt index 7773d483d3..9528fb2076 100644 --- a/app/src/main/java/chat/rocket/android/chatroom/adapter/MessageViewHolder.kt +++ b/app/src/main/java/chat/rocket/android/chatroom/adapter/MessageViewHolder.kt @@ -6,6 +6,8 @@ import android.text.Spannable import android.text.method.LinkMovementMethod import android.text.style.ImageSpan import android.view.View +import android.view.ViewGroup +import androidx.core.view.isGone import androidx.core.view.isVisible import chat.rocket.android.R import chat.rocket.android.chatroom.uimodel.MessageUiModel @@ -77,11 +79,31 @@ class MessageViewHolder( read_receipt_view.isVisible = true } - image_avatar.setOnClickListener { - data.message.sender?.id?.let { userId -> - avatarListener(userId) + if (!groupMessage) { + layout_avatar.isVisible = true + message_header.isVisible = true + + (text_content.layoutParams as ViewGroup.MarginLayoutParams).apply { + marginStart = 16.toPx.toInt() + } + + image_avatar.setOnClickListener { + data.message.sender?.id?.let { userId -> + avatarListener(userId) + } + } + } else { + layout_avatar.isGone = true + message_header.isGone = true + + (text_content.layoutParams as ViewGroup.MarginLayoutParams).apply { + marginStart = 56.toPx.toInt() } + + image_avatar.setOnClickListener(null) } + + } } diff --git a/app/src/main/res/layout/item_message.xml b/app/src/main/res/layout/item_message.xml index c9632ed562..d21f60ecf0 100644 --- a/app/src/main/res/layout/item_message.xml +++ b/app/src/main/res/layout/item_message.xml @@ -147,6 +147,7 @@