Fix long click not working for media timeline items (#3879)

This commit is contained in:
Jorge Martin Espinosa 2024-11-18 15:52:16 +01:00 committed by GitHub
parent 3b14e01dec
commit 1012272a08
11 changed files with 46 additions and 29 deletions

View file

@ -265,6 +265,7 @@ private fun TimelineItemEventContentViewWrapper(
eventSink = { }, eventSink = { },
modifier = modifier, modifier = modifier,
onContentClick = onContentClick, onContentClick = onContentClick,
onLongClick = null,
onContentLayoutChange = onContentLayoutChange onContentLayoutChange = onContentLayoutChange
) )
} }

View file

@ -30,7 +30,7 @@ internal fun ATimelineItemEventRow(
timelineProtectionState = timelineProtectionState, timelineProtectionState = timelineProtectionState,
isLastOutgoingMessage = isLastOutgoingMessage, isLastOutgoingMessage = isLastOutgoingMessage,
isHighlighted = isHighlighted, isHighlighted = isHighlighted,
onContentClick = {}, onEventClick = {},
onLongClick = {}, onLongClick = {},
onLinkClick = {}, onLinkClick = {},
onUserDataClick = {}, onUserDataClick = {},

View file

@ -114,7 +114,7 @@ fun TimelineItemEventRow(
renderReadReceipts: Boolean, renderReadReceipts: Boolean,
isLastOutgoingMessage: Boolean, isLastOutgoingMessage: Boolean,
isHighlighted: Boolean, isHighlighted: Boolean,
onContentClick: () -> Unit, onEventClick: () -> Unit,
onLongClick: () -> Unit, onLongClick: () -> Unit,
onLinkClick: (String) -> Unit, onLinkClick: (String) -> Unit,
onUserDataClick: (UserId) -> Unit, onUserDataClick: (UserId) -> Unit,
@ -127,10 +127,14 @@ fun TimelineItemEventRow(
eventSink: (TimelineEvents.EventFromTimelineItem) -> Unit, eventSink: (TimelineEvents.EventFromTimelineItem) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
eventContentView: @Composable (Modifier, (ContentAvoidingLayoutData) -> Unit) -> Unit = { contentModifier, onContentLayoutChange -> eventContentView: @Composable (Modifier, (ContentAvoidingLayoutData) -> Unit) -> Unit = { contentModifier, onContentLayoutChange ->
// Only pass down a custom clickable lambda if the content can be clicked separately
val onContentClick = onEventClick.takeUnless { event.isWholeContentClickable }
TimelineItemEventContentView( TimelineItemEventContentView(
content = event.content, content = event.content,
hideMediaContent = timelineProtectionState.hideMediaContent(event.eventId), hideMediaContent = timelineProtectionState.hideMediaContent(event.eventId),
onContentClick = onContentClick, onContentClick = onContentClick,
onLongClick = onLongClick,
onShowContentClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, onShowContentClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) },
onLinkClick = onLinkClick, onLinkClick = onLinkClick,
eventSink = eventSink, eventSink = eventSink,
@ -151,12 +155,6 @@ fun TimelineItemEventRow(
inReplyToClick(inReplyToEventId) inReplyToClick(inReplyToEventId)
} }
val onWholeItemClick = if (event.isWholeContentClickable) {
onContentClick
} else {
{}
}
Column(modifier = modifier.fillMaxWidth()) { Column(modifier = modifier.fillMaxWidth()) {
if (event.groupPosition.isNew()) { if (event.groupPosition.isNew()) {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
@ -180,7 +178,7 @@ fun TimelineItemEventRow(
isHighlighted = isHighlighted, isHighlighted = isHighlighted,
timelineRoomInfo = timelineRoomInfo, timelineRoomInfo = timelineRoomInfo,
interactionSource = interactionSource, interactionSource = interactionSource,
onContentClick = onWholeItemClick, onContentClick = onEventClick,
onLongClick = onLongClick, onLongClick = onLongClick,
inReplyToClick = ::inReplyToClick, inReplyToClick = ::inReplyToClick,
onUserDataClick = ::onUserDataClick, onUserDataClick = ::onUserDataClick,
@ -214,7 +212,7 @@ fun TimelineItemEventRow(
isHighlighted = isHighlighted, isHighlighted = isHighlighted,
timelineRoomInfo = timelineRoomInfo, timelineRoomInfo = timelineRoomInfo,
interactionSource = interactionSource, interactionSource = interactionSource,
onContentClick = onWholeItemClick, onContentClick = onEventClick,
onLongClick = onLongClick, onLongClick = onLongClick,
inReplyToClick = ::inReplyToClick, inReplyToClick = ::inReplyToClick,
onUserDataClick = ::onUserDataClick, onUserDataClick = ::onUserDataClick,

View file

@ -61,7 +61,8 @@ fun TimelineItemGroupedEventsRow(
onLinkClick = onLinkClick, onLinkClick = onLinkClick,
eventSink = eventSink, eventSink = eventSink,
modifier = contentModifier, modifier = contentModifier,
onContentClick = {}, onContentClick = null,
onLongClick = null,
onContentLayoutChange = onContentLayoutChange onContentLayoutChange = onContentLayoutChange
) )
}, },
@ -126,7 +127,8 @@ private fun TimelineItemGroupedEventsRowContent(
onLinkClick = onLinkClick, onLinkClick = onLinkClick,
eventSink = eventSink, eventSink = eventSink,
modifier = contentModifier, modifier = contentModifier,
onContentClick = {}, onContentClick = null,
onLongClick = null,
onContentLayoutChange = onContentLayoutChange onContentLayoutChange = onContentLayoutChange
) )
}, },

View file

@ -61,6 +61,7 @@ internal fun TimelineItemRow(
hideMediaContent = timelineProtectionState.hideMediaContent(event.eventId), hideMediaContent = timelineProtectionState.hideMediaContent(event.eventId),
onShowContentClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, onShowContentClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) },
onContentClick = { onContentClick(event) }, onContentClick = { onContentClick(event) },
onLongClick = { onLongClick(event) },
onLinkClick = onLinkClick, onLinkClick = onLinkClick,
eventSink = eventSink, eventSink = eventSink,
modifier = contentModifier, modifier = contentModifier,
@ -118,7 +119,7 @@ internal fun TimelineItemRow(
timelineProtectionState = timelineProtectionState, timelineProtectionState = timelineProtectionState,
isLastOutgoingMessage = isLastOutgoingMessage, isLastOutgoingMessage = isLastOutgoingMessage,
isHighlighted = timelineItem.isEvent(focusedEventId), isHighlighted = timelineItem.isEvent(focusedEventId),
onContentClick = { onContentClick(timelineItem) }, onEventClick = { onContentClick(timelineItem) },
onLongClick = { onLongClick(timelineItem) }, onLongClick = { onLongClick(timelineItem) },
onLinkClick = onLinkClick, onLinkClick = onLinkClick,
onUserDataClick = onUserDataClick, onUserDataClick = onUserDataClick,

View file

@ -74,7 +74,8 @@ fun TimelineItemStateEventRow(
hideMediaContent = false, hideMediaContent = false,
onShowContentClick = {}, onShowContentClick = {},
eventSink = eventSink, eventSink = eventSink,
onContentClick = {}, onContentClick = null,
onLongClick = null,
modifier = Modifier.defaultTimelineContentPadding() modifier = Modifier.defaultTimelineContentPadding()
) )
} }

View file

@ -36,7 +36,8 @@ import io.element.android.libraries.architecture.Presenter
fun TimelineItemEventContentView( fun TimelineItemEventContentView(
content: TimelineItemEventContent, content: TimelineItemEventContent,
hideMediaContent: Boolean, hideMediaContent: Boolean,
onContentClick: () -> Unit, onContentClick: (() -> Unit)?,
onLongClick: (() -> Unit)?,
onShowContentClick: () -> Unit, onShowContentClick: () -> Unit,
onLinkClick: (url: String) -> Unit, onLinkClick: (url: String) -> Unit,
eventSink: (TimelineEvents.EventFromTimelineItem) -> Unit, eventSink: (TimelineEvents.EventFromTimelineItem) -> Unit,
@ -68,13 +69,13 @@ fun TimelineItemEventContentView(
) )
is TimelineItemLocationContent -> TimelineItemLocationView( is TimelineItemLocationContent -> TimelineItemLocationView(
content = content, content = content,
onContentClick = onContentClick,
modifier = modifier modifier = modifier
) )
is TimelineItemImageContent -> TimelineItemImageView( is TimelineItemImageContent -> TimelineItemImageView(
content = content, content = content,
hideMediaContent = hideMediaContent, hideMediaContent = hideMediaContent,
onContentClick = onContentClick, onContentClick = onContentClick,
onLongClick = onLongClick,
onShowContentClick = onShowContentClick, onShowContentClick = onShowContentClick,
onLinkClick = onLinkClick, onLinkClick = onLinkClick,
onContentLayoutChange = onContentLayoutChange, onContentLayoutChange = onContentLayoutChange,
@ -84,6 +85,7 @@ fun TimelineItemEventContentView(
content = content, content = content,
hideMediaContent = hideMediaContent, hideMediaContent = hideMediaContent,
onContentClick = onContentClick, onContentClick = onContentClick,
onLongClick = onLongClick,
onShowClick = onShowContentClick, onShowClick = onShowContentClick,
modifier = modifier, modifier = modifier,
) )
@ -91,6 +93,7 @@ fun TimelineItemEventContentView(
content = content, content = content,
hideMediaContent = hideMediaContent, hideMediaContent = hideMediaContent,
onContentClick = onContentClick, onContentClick = onContentClick,
onLongClick = onLongClick,
onShowContentClick = onShowContentClick, onShowContentClick = onShowContentClick,
onLinkClick = onLinkClick, onLinkClick = onLinkClick,
onContentLayoutChange = onContentLayoutChange, onContentLayoutChange = onContentLayoutChange,

View file

@ -8,8 +8,9 @@
package io.element.android.features.messages.impl.timeline.components.event package io.element.android.features.messages.impl.timeline.components.event
import android.text.SpannedString import android.text.SpannedString
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@ -55,11 +56,13 @@ import io.element.android.libraries.textcomposer.ElementRichTextEditorStyle
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.wysiwyg.compose.EditorStyledText import io.element.android.wysiwyg.compose.EditorStyledText
@OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun TimelineItemImageView( fun TimelineItemImageView(
content: TimelineItemImageContent, content: TimelineItemImageContent,
hideMediaContent: Boolean, hideMediaContent: Boolean,
onContentClick: () -> Unit, onContentClick: (() -> Unit)?,
onLongClick: (() -> Unit)?,
onLinkClick: (String) -> Unit, onLinkClick: (String) -> Unit,
onShowContentClick: () -> Unit, onShowContentClick: () -> Unit,
onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit,
@ -87,7 +90,7 @@ fun TimelineItemImageView(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.then(if (isLoaded) Modifier.background(Color.White) else Modifier) .then(if (isLoaded) Modifier.background(Color.White) else Modifier)
.clickable(onClick = onContentClick), .then(if (onContentClick != null) Modifier.combinedClickable(onClick = onContentClick, onLongClick = onLongClick) else Modifier),
model = content.thumbnailMediaRequestData, model = content.thumbnailMediaRequestData,
contentScale = ContentScale.Fit, contentScale = ContentScale.Fit,
alignment = Alignment.Center, alignment = Alignment.Center,
@ -132,6 +135,7 @@ internal fun TimelineItemImageViewPreview(@PreviewParameter(TimelineItemImageCon
hideMediaContent = false, hideMediaContent = false,
onShowContentClick = {}, onShowContentClick = {},
onContentClick = {}, onContentClick = {},
onLongClick = {},
onLinkClick = {}, onLinkClick = {},
onContentLayoutChange = {}, onContentLayoutChange = {},
) )
@ -145,6 +149,7 @@ internal fun TimelineItemImageViewHideMediaContentPreview() = ElementPreview {
hideMediaContent = true, hideMediaContent = true,
onShowContentClick = {}, onShowContentClick = {},
onContentClick = {}, onContentClick = {},
onLongClick = {},
onLinkClick = {}, onLinkClick = {},
onContentLayoutChange = {}, onContentLayoutChange = {},
) )

View file

@ -7,7 +7,6 @@
package io.element.android.features.messages.impl.timeline.components.event 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.Column
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.heightIn
@ -26,10 +25,9 @@ import io.element.android.libraries.designsystem.theme.components.Text
@Composable @Composable
fun TimelineItemLocationView( fun TimelineItemLocationView(
content: TimelineItemLocationContent, content: TimelineItemLocationContent,
onContentClick: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Column(modifier = modifier.clickable(onClick = onContentClick).fillMaxWidth()) { Column(modifier = modifier.fillMaxWidth()) {
content.description?.let { content.description?.let {
Text( Text(
text = it, text = it,
@ -55,6 +53,5 @@ internal fun TimelineItemLocationViewPreview(@PreviewParameter(TimelineItemLocat
ElementPreview { ElementPreview {
TimelineItemLocationView( TimelineItemLocationView(
content = content, content = content,
onContentClick = {},
) )
} }

View file

@ -7,8 +7,9 @@
package io.element.android.features.messages.impl.timeline.components.event package io.element.android.features.messages.impl.timeline.components.event
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -37,11 +38,13 @@ import io.element.android.libraries.ui.strings.CommonStrings
private const val STICKER_SIZE_IN_DP = 128 private const val STICKER_SIZE_IN_DP = 128
@OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun TimelineItemStickerView( fun TimelineItemStickerView(
content: TimelineItemStickerContent, content: TimelineItemStickerContent,
hideMediaContent: Boolean, hideMediaContent: Boolean,
onContentClick: () -> Unit, onContentClick: (() -> Unit)?,
onLongClick: (() -> Unit)?,
onShowClick: () -> Unit, onShowClick: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
@ -64,7 +67,7 @@ fun TimelineItemStickerView(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.then(if (isLoaded) Modifier.background(Color.White) else Modifier) .then(if (isLoaded) Modifier.background(Color.White) else Modifier)
.clickable(onClick = onContentClick), .then(if (onContentClick != null) Modifier.combinedClickable(onClick = onContentClick, onLongClick = onLongClick) else Modifier),
model = MediaRequestData( model = MediaRequestData(
source = content.preferredMediaSource, source = content.preferredMediaSource,
kind = MediaRequestData.Kind.File( kind = MediaRequestData.Kind.File(
@ -89,6 +92,7 @@ internal fun TimelineItemStickerViewPreview(@PreviewParameter(TimelineItemSticke
content = content, content = content,
hideMediaContent = false, hideMediaContent = false,
onContentClick = {}, onContentClick = {},
onLongClick = {},
onShowClick = {}, onShowClick = {},
) )
} }

View file

@ -8,9 +8,10 @@
package io.element.android.features.messages.impl.timeline.components.event package io.element.android.features.messages.impl.timeline.components.event
import android.text.SpannedString import android.text.SpannedString
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
@ -64,11 +65,13 @@ import io.element.android.libraries.textcomposer.ElementRichTextEditorStyle
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.wysiwyg.compose.EditorStyledText import io.element.android.wysiwyg.compose.EditorStyledText
@OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun TimelineItemVideoView( fun TimelineItemVideoView(
content: TimelineItemVideoContent, content: TimelineItemVideoContent,
hideMediaContent: Boolean, hideMediaContent: Boolean,
onContentClick: () -> Unit, onContentClick: (() -> Unit)?,
onLongClick: (() -> Unit)?,
onShowContentClick: () -> Unit, onShowContentClick: () -> Unit,
onLinkClick: (String) -> Unit, onLinkClick: (String) -> Unit,
onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit,
@ -99,7 +102,7 @@ fun TimelineItemVideoView(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.then(if (isLoaded) Modifier.background(Color.White) else Modifier) .then(if (isLoaded) Modifier.background(Color.White) else Modifier)
.clickable(onClick = onContentClick), .then(if (onContentClick != null) Modifier.combinedClickable(onClick = onContentClick, onLongClick = onLongClick) else Modifier),
model = MediaRequestData( model = MediaRequestData(
source = content.thumbnailSource, source = content.thumbnailSource,
kind = MediaRequestData.Kind.Thumbnail( kind = MediaRequestData.Kind.Thumbnail(
@ -161,6 +164,7 @@ internal fun TimelineItemVideoViewPreview(@PreviewParameter(TimelineItemVideoCon
hideMediaContent = false, hideMediaContent = false,
onShowContentClick = {}, onShowContentClick = {},
onContentClick = {}, onContentClick = {},
onLongClick = {},
onLinkClick = {}, onLinkClick = {},
onContentLayoutChange = {}, onContentLayoutChange = {},
) )
@ -174,6 +178,7 @@ internal fun TimelineItemVideoViewHideMediaContentPreview() = ElementPreview {
hideMediaContent = true, hideMediaContent = true,
onShowContentClick = {}, onShowContentClick = {},
onContentClick = {}, onContentClick = {},
onLongClick = {},
onLinkClick = {}, onLinkClick = {},
onContentLayoutChange = {}, onContentLayoutChange = {},
) )