diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 529cf91c..36e56876 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -17,8 +17,10 @@ package im.vector.riotredesign.features.home.room.detail.timeline.factory import android.text.Spannable +import android.text.SpannableString import android.text.SpannableStringBuilder import androidx.annotation.ColorRes +import androidx.core.text.toSpannable import im.vector.matrix.android.api.permalinks.MatrixLinkify import im.vector.matrix.android.api.permalinks.MatrixPermalinkSpan import im.vector.matrix.android.api.session.events.model.EventType @@ -84,16 +86,16 @@ class MessageItemFactory(private val colorProvider: ColorProvider, return when (messageContent) { is MessageEmoteContent -> buildEmoteMessageItem(eventId, messageContent, informationData, callback) is MessageTextContent -> buildTextMessageItem(eventId, event.sendState, messageContent, informationData, callback) - is MessageImageContent -> buildImageMessageItem(messageContent, informationData, callback) + is MessageImageContent -> buildImageMessageItem(eventId, messageContent, informationData, callback) is MessageNoticeContent -> buildNoticeMessageItem(eventId, messageContent, informationData, callback) - is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, callback) - is MessageFileContent -> buildFileMessageItem(messageContent, informationData, callback) - is MessageAudioContent -> buildAudioMessageItem(messageContent, informationData, callback) + is MessageVideoContent -> buildVideoMessageItem(eventId, messageContent, informationData, callback) + is MessageFileContent -> buildFileMessageItem(eventId, messageContent, informationData, callback) + is MessageAudioContent -> buildAudioMessageItem(eventId, messageContent, informationData, callback) else -> buildNotHandledMessageItem(messageContent) } } - private fun buildAudioMessageItem(messageContent: MessageAudioContent, + private fun buildAudioMessageItem(eventId: String, messageContent: MessageAudioContent, informationData: MessageInformationData, callback: TimelineEventController.Callback?): MessageFileItem? { return MessageFileItem_() @@ -101,9 +103,13 @@ class MessageItemFactory(private val colorProvider: ColorProvider, .filename(messageContent.body) .iconRes(R.drawable.filetype_audio) .clickListener { _ -> callback?.onAudioMessageClicked(messageContent) } + .longClickListener { view -> + return@longClickListener callback?.onEventLongClicked(eventId, informationData, messageContent, view) + ?: false + } } - private fun buildFileMessageItem(messageContent: MessageFileContent, + private fun buildFileMessageItem(eventId: String, messageContent: MessageFileContent, informationData: MessageInformationData, callback: TimelineEventController.Callback?): MessageFileItem? { return MessageFileItem_() @@ -111,6 +117,10 @@ class MessageItemFactory(private val colorProvider: ColorProvider, .filename(messageContent.body) .iconRes(R.drawable.filetype_attachment) .clickListener { _ -> callback?.onFileMessageClicked(messageContent) } + .longClickListener { view -> + return@longClickListener callback?.onEventLongClicked(eventId, informationData, messageContent, view) + ?: false + } } private fun buildNotHandledMessageItem(messageContent: MessageContent): DefaultItem? { @@ -118,7 +128,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider, return DefaultItem_().text(text) } - private fun buildImageMessageItem(messageContent: MessageImageContent, + private fun buildImageMessageItem(eventId: String, messageContent: MessageImageContent, informationData: MessageInformationData, callback: TimelineEventController.Callback?): MessageImageVideoItem? { @@ -138,9 +148,13 @@ class MessageItemFactory(private val colorProvider: ColorProvider, .informationData(informationData) .mediaData(data) .clickListener { view -> callback?.onImageMessageClicked(messageContent, data, view) } + .longClickListener { view -> + return@longClickListener callback?.onEventLongClicked(eventId, informationData, messageContent, view) + ?: false + } } - private fun buildVideoMessageItem(messageContent: MessageVideoContent, + private fun buildVideoMessageItem(eventId: String, messageContent: MessageVideoContent, informationData: MessageInformationData, callback: TimelineEventController.Callback?): MessageImageVideoItem? { @@ -165,6 +179,10 @@ class MessageItemFactory(private val colorProvider: ColorProvider, .informationData(informationData) .mediaData(thumbnailData) .clickListener { view -> callback?.onVideoMessageClicked(messageContent, videoData, view) } + .longClickListener { view -> + return@longClickListener callback?.onEventLongClicked(eventId, informationData, messageContent, view) + ?: false + } } private fun buildTextMessageItem(eventId: String, sendState: SendState, @@ -224,7 +242,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider, } } - private fun linkifyBody(body: CharSequence, callback: TimelineEventController.Callback?): Spannable { + private fun linkifyBody(body: CharSequence, callback: TimelineEventController.Callback?): CharSequence { val spannable = SpannableStringBuilder(body) MatrixLinkify.addLinks(spannable, object : MatrixPermalinkSpan.Callback { override fun onUrlClicked(url: String) { diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt index 48687c78..cbcd6589 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt @@ -46,6 +46,7 @@ abstract class AbsMessageItem : VectorEpoxyModel() holder.timeView.visibility = View.GONE } holder.view.setOnLongClickListener(longClickListener) + } protected fun View.renderSendState() { diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageImageVideoItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageImageVideoItem.kt index 27e464b1..5ddf2e97 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageImageVideoItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageImageVideoItem.kt @@ -39,6 +39,7 @@ abstract class MessageImageVideoItem : AbsMessageItem() { - @EpoxyAttribute var message: Spannable? = null + @EpoxyAttribute var message: CharSequence? = null @EpoxyAttribute override lateinit var informationData: MessageInformationData override fun bind(holder: Holder) { @@ -53,7 +54,7 @@ abstract class MessageTextItem : AbsMessageItem() { private fun findPillsAndProcess(processBlock: (span: PillImageSpan) -> Unit) { GlobalScope.launch(Dispatchers.Main) { val pillImageSpans: Array? = withContext(Dispatchers.IO) { - message?.let { spannable -> + message?.toSpannable()?.let { spannable -> spannable.getSpans(0, spannable.length, PillImageSpan::class.java) } } diff --git a/vector/src/main/res/layout/item_timeline_event_file_message.xml b/vector/src/main/res/layout/item_timeline_event_file_message.xml index 83bc4815..58fa70df 100644 --- a/vector/src/main/res/layout/item_timeline_event_file_message.xml +++ b/vector/src/main/res/layout/item_timeline_event_file_message.xml @@ -19,6 +19,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" + android:addStatesFromChildren="true" android:paddingLeft="16dp" android:paddingRight="16dp"> @@ -58,7 +59,6 @@ android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" - android:duplicateParentState="true" android:textColor="@color/brown_grey" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" @@ -76,7 +76,6 @@ android:layout_marginEnd="32dp" android:layout_marginRight="32dp" android:layout_marginBottom="8dp" - android:duplicateParentState="true" android:orientation="horizontal" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0" diff --git a/vector/src/main/res/layout/item_timeline_event_image_video_message.xml b/vector/src/main/res/layout/item_timeline_event_image_video_message.xml index 17dd4f97..32e4ad2d 100644 --- a/vector/src/main/res/layout/item_timeline_event_image_video_message.xml +++ b/vector/src/main/res/layout/item_timeline_event_image_video_message.xml @@ -19,7 +19,9 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground" android:paddingLeft="16dp" + android:addStatesFromChildren="true" android:paddingRight="16dp"> @@ -58,7 +60,6 @@ android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" - android:duplicateParentState="true" android:textColor="@color/brown_grey" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" @@ -74,13 +75,13 @@ android:layout_marginTop="8dp" android:layout_marginEnd="32dp" android:layout_marginRight="32dp" - android:layout_marginBottom="8dp" - android:duplicateParentState="true" + android:foreground="?attr/selectableItemBackground" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/messageMemberNameView" - tools:layout_height="300dp" /> + tools:layout_height="300dp" + tools:srcCompat="@tools:sample/backgrounds/scenic" /> @@ -45,7 +46,6 @@ android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:textColor="@color/brown_grey" - android:duplicateParentState="true" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintTop_toTopOf="@id/messageMemberNameView" @@ -55,11 +55,10 @@ android:id="@+id/messageTextView" android:layout_width="0dp" android:layout_height="wrap_content" - android:foreground="?attr/selectableItemBackgroundBorderless" android:layout_marginStart="56dp" android:layout_marginLeft="56dp" android:layout_marginBottom="8dp" - android:duplicateParentState="true" + android:clickable="true" android:textColor="@color/dark_grey" android:textSize="14sp" app:layout_constraintBottom_toBottomOf="parent"