From 87976694d412ddeffaf9474025b6a89ea7b01c15 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Wed, 13 Nov 2024 20:25:34 +0100 Subject: [PATCH] Use formatted captions for images and video (#3864) * Make `formattedCaption in `TimelineItemEventContentWithAttachment` a `Charsequence?`, parse the formatted caption body as we do for text message bodies * Add `TimelineItem.isWholeContentClickable` property to decide whether the click action should be triggered at the message bubble level or when some internal content is tapped instead. * Display the formatted/linkified captions in image and video timeline item views * Apply the `onClick` callback to the whole message bubble or only the content of the timeline item depending on `TimelineItem.isWholeContentClickable`. --- .../features/messages/impl/MessagesNode.kt | 2 +- .../features/messages/impl/MessagesView.kt | 14 +++++------ .../MessagesViewWithIdentityChangePreview.kt | 2 +- .../pinned/list/PinnedMessagesListView.kt | 7 ++++-- .../messages/impl/timeline/TimelineView.kt | 6 ++--- .../TimelineViewMessageShieldPreview.kt | 2 +- .../components/ATimelineItemEventRow.kt | 2 +- .../components/TimelineItemEventRow.kt | 19 ++++++++++----- .../TimelineItemGroupedEventsRow.kt | 8 ++++--- .../timeline/components/TimelineItemRow.kt | 16 +++++-------- .../components/TimelineItemStateEventRow.kt | 3 ++- .../event/TimelineItemEventContentView.kt | 15 ++++++++---- .../components/event/TimelineItemImageView.kt | 24 ++++++++++++------- .../event/TimelineItemLocationView.kt | 9 +++++-- .../event/TimelineItemStickerView.kt | 6 ++++- .../components/event/TimelineItemVideoView.kt | 24 ++++++++++++------- .../TimelineItemContentMessageFactory.kt | 14 +++++------ .../impl/timeline/model/TimelineItem.kt | 13 ++++++++++ .../model/event/TimelineItemAudioContent.kt | 3 +-- .../model/event/TimelineItemEventContent.kt | 3 +-- .../model/event/TimelineItemFileContent.kt | 3 +-- .../model/event/TimelineItemImageContent.kt | 3 +-- .../model/event/TimelineItemStickerContent.kt | 3 +-- .../model/event/TimelineItemVideoContent.kt | 3 +-- .../model/event/TimelineItemVoiceContent.kt | 3 +-- .../messages/impl/MessagesViewTest.kt | 2 +- .../impl/timeline/TimelineViewTest.kt | 2 +- .../TimelineItemContentMessageFactoryTest.kt | 4 ++-- 28 files changed, 129 insertions(+), 86 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt index bf76f208e3..9fd823445f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt @@ -212,7 +212,7 @@ class MessagesNode @AssistedInject constructor( state = state, onBackClick = this::navigateUp, onRoomDetailsClick = this::onRoomDetailsClick, - onEventClick = this::onEventClick, + onEventContentClick = this::onEventClick, onPreviewAttachments = this::onPreviewAttachments, onUserDataClick = this::onUserDataClick, onLinkClick = { url -> onLinkClick(activity, isDark, url, state.timelineState.eventSink) }, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index e5d73fbed6..3e2918b3ce 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -114,7 +114,7 @@ fun MessagesView( state: MessagesState, onBackClick: () -> Unit, onRoomDetailsClick: () -> Unit, - onEventClick: (event: TimelineItem.Event) -> Boolean, + onEventContentClick: (event: TimelineItem.Event) -> Boolean, onUserDataClick: (UserId) -> Unit, onLinkClick: (String) -> Unit, onPreviewAttachments: (ImmutableList) -> Unit, @@ -142,9 +142,9 @@ fun MessagesView( // This is needed because the composer is inside an AndroidView that can't be affected by the FocusManager in Compose val localView = LocalView.current - fun onMessageClick(event: TimelineItem.Event) { + fun onContentClick(event: TimelineItem.Event) { Timber.v("onMessageClick= ${event.id}") - val hideKeyboard = onEventClick(event) + val hideKeyboard = onEventContentClick(event) if (hideKeyboard) { localView.hideKeyboard() } @@ -206,7 +206,7 @@ fun MessagesView( modifier = Modifier .padding(padding) .consumeWindowInsets(padding), - onMessageClick = ::onMessageClick, + onContentClick = ::onContentClick, onMessageLongClick = ::onMessageLongClick, onUserDataClick = onUserDataClick, onLinkClick = onLinkClick, @@ -306,7 +306,7 @@ private fun AttachmentStateView( @Composable private fun MessagesViewContent( state: MessagesState, - onMessageClick: (TimelineItem.Event) -> Unit, + onContentClick: (TimelineItem.Event) -> Unit, onUserDataClick: (UserId) -> Unit, onLinkClick: (String) -> Unit, onReactionClick: (key: String, TimelineItem.Event) -> Unit, @@ -382,7 +382,7 @@ private fun MessagesViewContent( timelineProtectionState = state.timelineProtectionState, onUserDataClick = onUserDataClick, onLinkClick = onLinkClick, - onMessageClick = onMessageClick, + onContentClick = onContentClick, onMessageLongClick = onMessageLongClick, onSwipeToReply = onSwipeToReply, onReactionClick = onReactionClick, @@ -568,7 +568,7 @@ internal fun MessagesViewPreview(@PreviewParameter(MessagesStateProvider::class) state = state, onBackClick = {}, onRoomDetailsClick = {}, - onEventClick = { false }, + onEventContentClick = { false }, onUserDataClick = {}, onLinkClick = {}, onPreviewAttachments = {}, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/identity/MessagesViewWithIdentityChangePreview.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/identity/MessagesViewWithIdentityChangePreview.kt index c34f072c6d..04750b6ad8 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/identity/MessagesViewWithIdentityChangePreview.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/identity/MessagesViewWithIdentityChangePreview.kt @@ -33,7 +33,7 @@ internal fun MessagesViewWithIdentityChangePreview( ), onBackClick = {}, onRoomDetailsClick = {}, - onEventClick = { false }, + onEventContentClick = { false }, onUserDataClick = {}, onLinkClick = {}, onPreviewAttachments = {}, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListView.kt index f4a3247cba..7ae88b9647 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListView.kt @@ -216,7 +216,7 @@ private fun PinnedMessagesListLoaded( focusedEventId = null, onUserDataClick = onUserDataClick, onLinkClick = onLinkClick, - onClick = onEventClick, + onContentClick = onEventClick, onLongClick = ::onMessageLongClick, inReplyToClick = {}, onReactionClick = { _, _ -> }, @@ -230,6 +230,7 @@ private fun PinnedMessagesListLoaded( TimelineItemEventContentViewWrapper( event = event, timelineProtectionState = state.timelineProtectionState, + onContentClick = { onEventClick(event) }, onLinkClick = onLinkClick, modifier = contentModifier, onContentLayoutChange = onContentLayoutChange @@ -244,6 +245,7 @@ private fun PinnedMessagesListLoaded( private fun TimelineItemEventContentViewWrapper( event: TimelineItem.Event, timelineProtectionState: TimelineProtectionState, + onContentClick: () -> Unit, onLinkClick: (String) -> Unit, onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, modifier: Modifier = Modifier, @@ -258,10 +260,11 @@ private fun TimelineItemEventContentViewWrapper( TimelineItemEventContentView( content = event.content, hideMediaContent = timelineProtectionState.hideMediaContent(event.eventId), - onShowClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, + onShowContentClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, onLinkClick = onLinkClick, eventSink = { }, modifier = modifier, + onContentClick = onContentClick, onContentLayoutChange = onContentLayoutChange ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt index f0e976e368..6e34bba9e1 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt @@ -76,7 +76,7 @@ fun TimelineView( timelineProtectionState: TimelineProtectionState, onUserDataClick: (UserId) -> Unit, onLinkClick: (String) -> Unit, - onMessageClick: (TimelineItem.Event) -> Unit, + onContentClick: (TimelineItem.Event) -> Unit, onMessageLongClick: (TimelineItem.Event) -> Unit, onSwipeToReply: (TimelineItem.Event) -> Unit, onReactionClick: (emoji: String, TimelineItem.Event) -> Unit, @@ -141,7 +141,7 @@ fun TimelineView( focusedEventId = state.focusedEventId, onUserDataClick = onUserDataClick, onLinkClick = onLinkClick, - onClick = onMessageClick, + onContentClick = onContentClick, onLongClick = onMessageLongClick, inReplyToClick = ::inReplyToClick, onReactionClick = onReactionClick, @@ -322,7 +322,7 @@ internal fun TimelineViewPreview( timelineProtectionState = aTimelineProtectionState(), onUserDataClick = {}, onLinkClick = {}, - onMessageClick = {}, + onContentClick = {}, onMessageLongClick = {}, onSwipeToReply = {}, onReactionClick = { _, _ -> }, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewMessageShieldPreview.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewMessageShieldPreview.kt index 99f69675fa..462e74137a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewMessageShieldPreview.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewMessageShieldPreview.kt @@ -41,7 +41,7 @@ internal fun TimelineViewMessageShieldPreview() = ElementPreview { timelineProtectionState = aTimelineProtectionState(), onUserDataClick = {}, onLinkClick = {}, - onMessageClick = {}, + onContentClick = {}, onMessageLongClick = {}, onSwipeToReply = {}, onReactionClick = { _, _ -> }, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt index 1fa5e7f9a1..85e9854919 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt @@ -30,7 +30,7 @@ internal fun ATimelineItemEventRow( timelineProtectionState = timelineProtectionState, isLastOutgoingMessage = isLastOutgoingMessage, isHighlighted = isHighlighted, - onClick = {}, + onContentClick = {}, onLongClick = {}, onLinkClick = {}, onUserDataClick = {}, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index 2f0165cd7b..0061ebe6df 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -114,7 +114,7 @@ fun TimelineItemEventRow( renderReadReceipts: Boolean, isLastOutgoingMessage: Boolean, isHighlighted: Boolean, - onClick: () -> Unit, + onContentClick: () -> Unit, onLongClick: () -> Unit, onLinkClick: (String) -> Unit, onUserDataClick: (UserId) -> Unit, @@ -130,7 +130,8 @@ fun TimelineItemEventRow( TimelineItemEventContentView( content = event.content, hideMediaContent = timelineProtectionState.hideMediaContent(event.eventId), - onShowClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, + onContentClick = onContentClick, + onShowContentClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, onLinkClick = onLinkClick, eventSink = eventSink, modifier = contentModifier, @@ -150,6 +151,12 @@ fun TimelineItemEventRow( inReplyToClick(inReplyToEventId) } + val onWholeItemClick = if (event.isWholeContentClickable) { + onContentClick + } else { + {} + } + Column(modifier = modifier.fillMaxWidth()) { if (event.groupPosition.isNew()) { Spacer(modifier = Modifier.height(16.dp)) @@ -173,7 +180,7 @@ fun TimelineItemEventRow( isHighlighted = isHighlighted, timelineRoomInfo = timelineRoomInfo, interactionSource = interactionSource, - onClick = onClick, + onContentClick = onWholeItemClick, onLongClick = onLongClick, inReplyToClick = ::inReplyToClick, onUserDataClick = ::onUserDataClick, @@ -207,7 +214,7 @@ fun TimelineItemEventRow( isHighlighted = isHighlighted, timelineRoomInfo = timelineRoomInfo, interactionSource = interactionSource, - onClick = onClick, + onContentClick = onWholeItemClick, onLongClick = onLongClick, inReplyToClick = ::inReplyToClick, onUserDataClick = ::onUserDataClick, @@ -263,7 +270,7 @@ private fun TimelineItemEventRowContent( isHighlighted: Boolean, timelineRoomInfo: TimelineRoomInfo, interactionSource: MutableInteractionSource, - onClick: () -> Unit, + onContentClick: () -> Unit, onLongClick: () -> Unit, inReplyToClick: () -> Unit, onUserDataClick: () -> Unit, @@ -340,7 +347,7 @@ private fun TimelineItemEventRowContent( }, state = bubbleState, interactionSource = interactionSource, - onClick = onClick, + onClick = onContentClick, onLongClick = onLongClick, ) { MessageEventBubbleContent( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt index d280efa62c..fe89d6de02 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt @@ -57,10 +57,11 @@ fun TimelineItemGroupedEventsRow( TimelineItemEventContentView( content = event.content, hideMediaContent = timelineProtectionState.hideMediaContent(event.eventId), - onShowClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, + onShowContentClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, onLinkClick = onLinkClick, eventSink = eventSink, modifier = contentModifier, + onContentClick = {}, onContentLayoutChange = onContentLayoutChange ) }, @@ -121,10 +122,11 @@ private fun TimelineItemGroupedEventsRowContent( TimelineItemEventContentView( content = event.content, hideMediaContent = timelineProtectionState.hideMediaContent(event.eventId), - onShowClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, + onShowContentClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, onLinkClick = onLinkClick, eventSink = eventSink, modifier = contentModifier, + onContentClick = {}, onContentLayoutChange = onContentLayoutChange ) }, @@ -152,7 +154,7 @@ private fun TimelineItemGroupedEventsRowContent( focusedEventId = focusedEventId, onUserDataClick = onUserDataClick, onLinkClick = onLinkClick, - onClick = onClick, + onContentClick = onClick, onLongClick = onLongClick, inReplyToClick = inReplyToClick, onReactionClick = onReactionClick, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt index 13c247645b..047f9b3d04 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt @@ -28,7 +28,6 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionEvent import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionState -import io.element.android.features.messages.impl.timeline.protection.mustBeProtected import io.element.android.libraries.designsystem.text.toPx import io.element.android.libraries.designsystem.theme.highlightedMessageBackgroundColor import io.element.android.libraries.matrix.api.core.EventId @@ -44,7 +43,7 @@ internal fun TimelineItemRow( focusedEventId: EventId?, onUserDataClick: (UserId) -> Unit, onLinkClick: (String) -> Unit, - onClick: (TimelineItem.Event) -> Unit, + onContentClick: (TimelineItem.Event) -> Unit, onLongClick: (TimelineItem.Event) -> Unit, inReplyToClick: (EventId) -> Unit, onReactionClick: (key: String, TimelineItem.Event) -> Unit, @@ -60,7 +59,8 @@ internal fun TimelineItemRow( TimelineItemEventContentView( content = event.content, hideMediaContent = timelineProtectionState.hideMediaContent(event.eventId), - onShowClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, + onShowContentClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, + onContentClick = { onContentClick(event) }, onLinkClick = onLinkClick, eventSink = eventSink, modifier = contentModifier, @@ -95,7 +95,7 @@ internal fun TimelineItemRow( renderReadReceipts = renderReadReceipts, isLastOutgoingMessage = isLastOutgoingMessage, isHighlighted = timelineItem.isEvent(focusedEventId), - onClick = { onClick(timelineItem) }, + onClick = { onContentClick(timelineItem) }, onReadReceiptsClick = onReadReceiptClick, onLongClick = { onLongClick(timelineItem) }, eventSink = eventSink, @@ -118,11 +118,7 @@ internal fun TimelineItemRow( timelineProtectionState = timelineProtectionState, isLastOutgoingMessage = isLastOutgoingMessage, isHighlighted = timelineItem.isEvent(focusedEventId), - onClick = if (timelineProtectionState.hideMediaContent(timelineItem.eventId) && timelineItem.mustBeProtected()) { - {} - } else { - { onClick(timelineItem) } - }, + onContentClick = { onContentClick(timelineItem) }, onLongClick = { onLongClick(timelineItem) }, onLinkClick = onLinkClick, onUserDataClick = onUserDataClick, @@ -148,7 +144,7 @@ internal fun TimelineItemRow( renderReadReceipts = renderReadReceipts, isLastOutgoingMessage = isLastOutgoingMessage, focusedEventId = focusedEventId, - onClick = onClick, + onClick = onContentClick, onLongClick = onLongClick, inReplyToClick = inReplyToClick, onUserDataClick = onUserDataClick, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemStateEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemStateEventRow.kt index f023a63c35..6172686016 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemStateEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemStateEventRow.kt @@ -72,8 +72,9 @@ fun TimelineItemStateEventRow( content = event.content, onLinkClick = {}, hideMediaContent = false, - onShowClick = {}, + onShowContentClick = {}, eventSink = eventSink, + onContentClick = {}, modifier = Modifier.defaultTimelineContentPadding() ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemEventContentView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemEventContentView.kt index b24a5ca0be..3a3a43a6fc 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemEventContentView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemEventContentView.kt @@ -36,7 +36,8 @@ import io.element.android.libraries.architecture.Presenter fun TimelineItemEventContentView( content: TimelineItemEventContent, hideMediaContent: Boolean, - onShowClick: () -> Unit, + onContentClick: () -> Unit, + onShowContentClick: () -> Unit, onLinkClick: (url: String) -> Unit, eventSink: (TimelineEvents.EventFromTimelineItem) -> Unit, modifier: Modifier = Modifier, @@ -67,25 +68,31 @@ fun TimelineItemEventContentView( ) is TimelineItemLocationContent -> TimelineItemLocationView( content = content, + onContentClick = onContentClick, modifier = modifier ) is TimelineItemImageContent -> TimelineItemImageView( content = content, hideMediaContent = hideMediaContent, - onShowClick = onShowClick, + onContentClick = onContentClick, + onShowContentClick = onShowContentClick, + onLinkClick = onLinkClick, onContentLayoutChange = onContentLayoutChange, modifier = modifier, ) is TimelineItemStickerContent -> TimelineItemStickerView( content = content, hideMediaContent = hideMediaContent, - onShowClick = onShowClick, + onContentClick = onContentClick, + onShowClick = onShowContentClick, modifier = modifier, ) is TimelineItemVideoContent -> TimelineItemVideoView( content = content, hideMediaContent = hideMediaContent, - onShowClick = onShowClick, + onContentClick = onContentClick, + onShowContentClick = onShowContentClick, + onLinkClick = onLinkClick, onContentLayoutChange = onContentLayoutChange, modifier = modifier ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt index 63bbac7f6f..123ba195f1 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt @@ -9,6 +9,7 @@ package io.element.android.features.messages.impl.timeline.components.event import android.text.SpannedString import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth @@ -50,7 +51,6 @@ import io.element.android.features.messages.impl.timeline.protection.ProtectedVi import io.element.android.libraries.designsystem.components.blurhash.blurHashBackground import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.matrix.api.timeline.item.event.MessageFormat import io.element.android.libraries.textcomposer.ElementRichTextEditorStyle import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.wysiwyg.compose.EditorStyledText @@ -59,7 +59,9 @@ import io.element.android.wysiwyg.compose.EditorStyledText fun TimelineItemImageView( content: TimelineItemImageContent, hideMediaContent: Boolean, - onShowClick: () -> Unit, + onContentClick: () -> Unit, + onLinkClick: (String) -> Unit, + onShowContentClick: () -> Unit, onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, modifier: Modifier = Modifier, ) { @@ -78,13 +80,14 @@ fun TimelineItemImageView( ) { ProtectedView( hideContent = hideMediaContent, - onShowClick = onShowClick, + onShowClick = onShowContentClick, ) { var isLoaded by remember { mutableStateOf(false) } AsyncImage( modifier = Modifier .fillMaxWidth() - .then(if (isLoaded) Modifier.background(Color.White) else Modifier), + .then(if (isLoaded) Modifier.background(Color.White) else Modifier) + .clickable(onClick = onContentClick), model = content.thumbnailMediaRequestData, contentScale = ContentScale.Fit, alignment = Alignment.Center, @@ -99,9 +102,7 @@ fun TimelineItemImageView( val caption = if (LocalInspectionMode.current) { SpannedString(content.caption) } else { - content.formattedCaption?.body - ?.takeIf { content.formattedCaption.format == MessageFormat.HTML } - ?: SpannedString(content.caption) + content.formattedCaption ?: SpannedString(content.caption) } CompositionLocalProvider( LocalContentColor provides ElementTheme.colors.textPrimary, @@ -114,6 +115,7 @@ fun TimelineItemImageView( .widthIn(min = MIN_HEIGHT_IN_DP.dp * aspectRatio, max = MAX_HEIGHT_IN_DP.dp * aspectRatio), text = caption, style = ElementRichTextEditorStyle.textStyle(), + onLinkClickedListener = onLinkClick, releaseOnDetach = false, onTextLayout = ContentAvoidingLayout.measureLegacyLastTextLine(onContentLayoutChange = onContentLayoutChange), ) @@ -128,7 +130,9 @@ internal fun TimelineItemImageViewPreview(@PreviewParameter(TimelineItemImageCon TimelineItemImageView( content = content, hideMediaContent = false, - onShowClick = {}, + onShowContentClick = {}, + onContentClick = {}, + onLinkClick = {}, onContentLayoutChange = {}, ) } @@ -139,7 +143,9 @@ internal fun TimelineItemImageViewHideMediaContentPreview() = ElementPreview { TimelineItemImageView( content = aTimelineItemImageContent(), hideMediaContent = true, - onShowClick = {}, + onShowContentClick = {}, + onContentClick = {}, + onLinkClick = {}, onContentLayoutChange = {}, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt index 91cfcff1d8..5d402bc8f1 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt @@ -7,6 +7,7 @@ package io.element.android.features.messages.impl.timeline.components.event +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn @@ -25,9 +26,10 @@ import io.element.android.libraries.designsystem.theme.components.Text @Composable fun TimelineItemLocationView( content: TimelineItemLocationContent, + onContentClick: () -> Unit, modifier: Modifier = Modifier, ) { - Column(modifier = modifier.fillMaxWidth()) { + Column(modifier = modifier.clickable(onClick = onContentClick).fillMaxWidth()) { content.description?.let { Text( text = it, @@ -51,5 +53,8 @@ fun TimelineItemLocationView( @Composable internal fun TimelineItemLocationViewPreview(@PreviewParameter(TimelineItemLocationContentProvider::class) content: TimelineItemLocationContent) = ElementPreview { - TimelineItemLocationView(content) + TimelineItemLocationView( + content = content, + onContentClick = {}, + ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt index 0574843dba..df087769ed 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt @@ -8,6 +8,7 @@ package io.element.android.features.messages.impl.timeline.components.event import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable @@ -40,6 +41,7 @@ private const val STICKER_SIZE_IN_DP = 128 fun TimelineItemStickerView( content: TimelineItemStickerContent, hideMediaContent: Boolean, + onContentClick: () -> Unit, onShowClick: () -> Unit, modifier: Modifier = Modifier, ) { @@ -61,7 +63,8 @@ fun TimelineItemStickerView( AsyncImage( modifier = Modifier .fillMaxSize() - .then(if (isLoaded) Modifier.background(Color.White) else Modifier), + .then(if (isLoaded) Modifier.background(Color.White) else Modifier) + .clickable(onClick = onContentClick), model = MediaRequestData( source = content.preferredMediaSource, kind = MediaRequestData.Kind.File( @@ -85,6 +88,7 @@ internal fun TimelineItemStickerViewPreview(@PreviewParameter(TimelineItemSticke TimelineItemStickerView( content = content, hideMediaContent = false, + onContentClick = {}, onShowClick = {}, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt index 64e6d00d71..65f59cd631 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt @@ -10,6 +10,7 @@ package io.element.android.features.messages.impl.timeline.components.event import android.text.SpannedString import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -56,7 +57,6 @@ import io.element.android.libraries.designsystem.components.blurhash.blurHashBac import io.element.android.libraries.designsystem.modifiers.roundedBackground import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.matrix.api.timeline.item.event.MessageFormat import io.element.android.libraries.matrix.ui.media.MAX_THUMBNAIL_HEIGHT import io.element.android.libraries.matrix.ui.media.MAX_THUMBNAIL_WIDTH import io.element.android.libraries.matrix.ui.media.MediaRequestData @@ -68,7 +68,9 @@ import io.element.android.wysiwyg.compose.EditorStyledText fun TimelineItemVideoView( content: TimelineItemVideoContent, hideMediaContent: Boolean, - onShowClick: () -> Unit, + onContentClick: () -> Unit, + onShowContentClick: () -> Unit, + onLinkClick: (String) -> Unit, onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, modifier: Modifier = Modifier, ) { @@ -90,13 +92,14 @@ fun TimelineItemVideoView( ) { ProtectedView( hideContent = hideMediaContent, - onShowClick = onShowClick, + onShowClick = onShowContentClick, ) { var isLoaded by remember { mutableStateOf(false) } AsyncImage( modifier = Modifier .fillMaxWidth() - .then(if (isLoaded) Modifier.background(Color.White) else Modifier), + .then(if (isLoaded) Modifier.background(Color.White) else Modifier) + .clickable(onClick = onContentClick), model = MediaRequestData( source = content.thumbnailSource, kind = MediaRequestData.Kind.Thumbnail( @@ -128,9 +131,7 @@ fun TimelineItemVideoView( val caption = if (LocalInspectionMode.current) { SpannedString(content.caption) } else { - content.formattedCaption?.body - ?.takeIf { content.formattedCaption.format == MessageFormat.HTML } - ?: SpannedString(content.caption) + content.formattedCaption ?: SpannedString(content.caption) } CompositionLocalProvider( LocalContentColor provides ElementTheme.colors.textPrimary, @@ -142,6 +143,7 @@ fun TimelineItemVideoView( .padding(horizontal = 4.dp) // This is (12.dp - 8.dp) contentPadding from CommonLayout .widthIn(min = MIN_HEIGHT_IN_DP.dp * aspectRatio, max = MAX_HEIGHT_IN_DP.dp * aspectRatio), text = caption, + onLinkClickedListener = onLinkClick, style = ElementRichTextEditorStyle.textStyle(), releaseOnDetach = false, onTextLayout = ContentAvoidingLayout.measureLegacyLastTextLine(onContentLayoutChange = onContentLayoutChange), @@ -157,7 +159,9 @@ internal fun TimelineItemVideoViewPreview(@PreviewParameter(TimelineItemVideoCon TimelineItemVideoView( content = content, hideMediaContent = false, - onShowClick = {}, + onShowContentClick = {}, + onContentClick = {}, + onLinkClick = {}, onContentLayoutChange = {}, ) } @@ -168,7 +172,9 @@ internal fun TimelineItemVideoViewHideMediaContentPreview() = ElementPreview { TimelineItemVideoView( content = aTimelineItemVideoContent(), hideMediaContent = true, - onShowClick = {}, + onShowContentClick = {}, + onContentClick = {}, + onLinkClick = {}, onContentLayoutChange = {}, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt index 001d40b254..ff5ca57c11 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt @@ -86,7 +86,7 @@ class TimelineItemContentMessageFactory @Inject constructor( TimelineItemImageContent( filename = messageType.filename, caption = messageType.caption?.trimEnd(), - formattedCaption = messageType.formattedCaption, + formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), mediaSource = messageType.source, thumbnailSource = messageType.info?.thumbnailSource, mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream, @@ -105,7 +105,7 @@ class TimelineItemContentMessageFactory @Inject constructor( TimelineItemStickerContent( filename = messageType.filename, caption = messageType.caption?.trimEnd(), - formattedCaption = messageType.formattedCaption, + formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), mediaSource = messageType.source, thumbnailSource = messageType.info?.thumbnailSource, mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream, @@ -142,7 +142,7 @@ class TimelineItemContentMessageFactory @Inject constructor( TimelineItemVideoContent( filename = messageType.filename, caption = messageType.caption?.trimEnd(), - formattedCaption = messageType.formattedCaption, + formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), thumbnailSource = messageType.info?.thumbnailSource, videoSource = messageType.source, mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream, @@ -161,7 +161,7 @@ class TimelineItemContentMessageFactory @Inject constructor( TimelineItemAudioContent( filename = messageType.filename, caption = messageType.caption?.trimEnd(), - formattedCaption = messageType.formattedCaption, + formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), mediaSource = messageType.source, duration = messageType.info?.duration ?: Duration.ZERO, mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream, @@ -176,7 +176,7 @@ class TimelineItemContentMessageFactory @Inject constructor( eventId = eventId, filename = messageType.filename, caption = messageType.caption?.trimEnd(), - formattedCaption = messageType.formattedCaption, + formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), mediaSource = messageType.source, duration = messageType.info?.duration ?: Duration.ZERO, mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream, @@ -187,7 +187,7 @@ class TimelineItemContentMessageFactory @Inject constructor( TimelineItemAudioContent( filename = messageType.filename, caption = messageType.caption?.trimEnd(), - formattedCaption = messageType.formattedCaption, + formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), mediaSource = messageType.source, duration = messageType.info?.duration ?: Duration.ZERO, mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream, @@ -202,7 +202,7 @@ class TimelineItemContentMessageFactory @Inject constructor( TimelineItemFileContent( filename = messageType.filename, caption = messageType.caption?.trimEnd(), - formattedCaption = messageType.formattedCaption, + formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), thumbnailSource = messageType.info?.thumbnailSource, fileSource = messageType.source, mimeType = messageType.info?.mimetype ?: MimeTypes.fromFileExtension(fileExtension), diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt index dcf0e16aa8..e2c81a3794 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt @@ -9,8 +9,10 @@ package io.element.android.features.messages.impl.timeline.model import androidx.compose.runtime.Immutable import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStickerContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemVirtualModel import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.matrix.api.core.EventId @@ -93,6 +95,17 @@ sealed interface TimelineItem { val isRemote = eventId != null + /** Whether a click on any part of the event bubble should trigger the 'onContentClick' callback. + * + * This is `true` for all events except for visual media events with a caption or formatted caption. + */ + val isWholeContentClickable = when (content) { + is TimelineItemStickerContent -> content.formattedCaption == null && content.caption == null + is TimelineItemImageContent -> content.formattedCaption == null && content.caption == null + is TimelineItemVideoContent -> content.formattedCaption == null && content.caption == null + else -> true + } + val eventOrTransactionId: EventOrTransactionId get() = EventOrTransactionId.from(eventId = eventId, transactionId = transactionId) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt index fa2957b860..0ecf45ec55 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt @@ -8,14 +8,13 @@ package io.element.android.features.messages.impl.timeline.model.event import io.element.android.libraries.matrix.api.media.MediaSource -import io.element.android.libraries.matrix.api.timeline.item.event.FormattedBody import io.element.android.libraries.mediaviewer.api.helper.formatFileExtensionAndSize import kotlin.time.Duration data class TimelineItemAudioContent( override val filename: String, override val caption: String?, - override val formattedCaption: FormattedBody?, + override val formattedCaption: CharSequence?, val duration: Duration, val mediaSource: MediaSource, val mimeType: String, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt index 10204a75d8..fafadcbf79 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt @@ -8,7 +8,6 @@ package io.element.android.features.messages.impl.timeline.model.event import androidx.compose.runtime.Immutable -import io.element.android.libraries.matrix.api.timeline.item.event.FormattedBody @Immutable sealed interface TimelineItemEventContent { @@ -19,7 +18,7 @@ sealed interface TimelineItemEventContent { sealed interface TimelineItemEventContentWithAttachment : TimelineItemEventContent { val filename: String val caption: String? - val formattedCaption: FormattedBody? + val formattedCaption: CharSequence? val bestDescription: String get() = caption ?: filename diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt index f11325727c..b7007c8bbc 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt @@ -8,13 +8,12 @@ package io.element.android.features.messages.impl.timeline.model.event import io.element.android.libraries.matrix.api.media.MediaSource -import io.element.android.libraries.matrix.api.timeline.item.event.FormattedBody import io.element.android.libraries.mediaviewer.api.helper.formatFileExtensionAndSize data class TimelineItemFileContent( override val filename: String, override val caption: String?, - override val formattedCaption: FormattedBody?, + override val formattedCaption: CharSequence?, val fileSource: MediaSource, val thumbnailSource: MediaSource?, val formattedFileSize: String, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt index e6e4bffb9b..b13c7a4e37 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt @@ -9,7 +9,6 @@ package io.element.android.features.messages.impl.timeline.model.event import io.element.android.libraries.core.mimetype.MimeTypes.isMimeTypeAnimatedImage import io.element.android.libraries.matrix.api.media.MediaSource -import io.element.android.libraries.matrix.api.timeline.item.event.FormattedBody import io.element.android.libraries.matrix.ui.media.MAX_THUMBNAIL_HEIGHT import io.element.android.libraries.matrix.ui.media.MAX_THUMBNAIL_WIDTH import io.element.android.libraries.matrix.ui.media.MediaRequestData @@ -17,7 +16,7 @@ import io.element.android.libraries.matrix.ui.media.MediaRequestData data class TimelineItemImageContent( override val filename: String, override val caption: String?, - override val formattedCaption: FormattedBody?, + override val formattedCaption: CharSequence?, val mediaSource: MediaSource, val thumbnailSource: MediaSource?, val formattedFileSize: String, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContent.kt index 3476d97e2f..06886307ae 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContent.kt @@ -8,12 +8,11 @@ package io.element.android.features.messages.impl.timeline.model.event import io.element.android.libraries.matrix.api.media.MediaSource -import io.element.android.libraries.matrix.api.timeline.item.event.FormattedBody data class TimelineItemStickerContent( override val filename: String, override val caption: String?, - override val formattedCaption: FormattedBody?, + override val formattedCaption: CharSequence?, val mediaSource: MediaSource, val thumbnailSource: MediaSource?, val formattedFileSize: String, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt index 5c0e601708..486a71b5d4 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt @@ -8,13 +8,12 @@ package io.element.android.features.messages.impl.timeline.model.event import io.element.android.libraries.matrix.api.media.MediaSource -import io.element.android.libraries.matrix.api.timeline.item.event.FormattedBody import kotlin.time.Duration data class TimelineItemVideoContent( override val filename: String, override val caption: String?, - override val formattedCaption: FormattedBody?, + override val formattedCaption: CharSequence?, val duration: Duration, val videoSource: MediaSource, val thumbnailSource: MediaSource?, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContent.kt index 853cc01045..ebeabef715 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContent.kt @@ -9,7 +9,6 @@ package io.element.android.features.messages.impl.timeline.model.event import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.media.MediaSource -import io.element.android.libraries.matrix.api.timeline.item.event.FormattedBody import kotlinx.collections.immutable.ImmutableList import kotlin.time.Duration @@ -17,7 +16,7 @@ data class TimelineItemVoiceContent( val eventId: EventId?, override val filename: String, override val caption: String?, - override val formattedCaption: FormattedBody?, + override val formattedCaption: CharSequence?, val duration: Duration, val mediaSource: MediaSource, val mimeType: String, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt index a20acaa5df..c040ce9926 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt @@ -529,7 +529,7 @@ private fun AndroidComposeTestRule.setMessa state = state, onBackClick = onBackClick, onRoomDetailsClick = onRoomDetailsClick, - onEventClick = onEventClick, + onEventContentClick = onEventClick, onUserDataClick = onUserDataClick, onLinkClick = onLinkClick, onPreviewAttachments = onPreviewAttachments, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt index 315abd8302..6a7b49c34c 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt @@ -158,7 +158,7 @@ private fun AndroidComposeTestRule.setTimel timelineProtectionState = timelineProtectionState, onUserDataClick = onUserDataClick, onLinkClick = onLinkClick, - onMessageClick = onMessageClick, + onContentClick = onMessageClick, onMessageLongClick = onMessageLongClick, onSwipeToReply = onSwipeToReply, onReactionClick = onReactionClick, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt index e9343bf21d..a34e601e5d 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt @@ -286,7 +286,7 @@ class TimelineItemContentMessageFactoryTest { val expected = TimelineItemVideoContent( filename = "body.mp4", caption = "body.mp4 caption", - formattedCaption = FormattedBody(MessageFormat.HTML, "formatted"), + formattedCaption = SpannedString("formatted"), duration = 1.minutes, videoSource = MediaSource(url = "url", json = null), thumbnailSource = MediaSource("url_thumbnail"), @@ -527,7 +527,7 @@ class TimelineItemContentMessageFactoryTest { ) val expected = TimelineItemImageContent( filename = "body.jpg", - formattedCaption = FormattedBody(MessageFormat.HTML, "formatted"), + formattedCaption = SpannedString("formatted"), caption = "body.jpg caption", mediaSource = MediaSource(url = "url", json = null), thumbnailSource = MediaSource("url_thumbnail"),