Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContentWithAttachment
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemGalleryContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent
Expand Down Expand Up @@ -143,10 +144,11 @@ class MessagesFlowNode(
val mediaInfo: MediaInfo,
val mediaSource: MediaSource,
val thumbnailSource: MediaSource?,
val galleryItems: List<io.element.android.libraries.mediaviewer.api.GalleryItemData> = emptyList(),
) : NavTarget

@Parcelize
data class AttachmentPreview(val timelineMode: Timeline.Mode, val attachment: Attachment, val inReplyToEventId: EventId?) : NavTarget
data class AttachmentPreview(val timelineMode: Timeline.Mode, val attachments: ImmutableList<Attachment>, val inReplyToEventId: EventId?) : NavTarget

@Parcelize
data class LocationViewer(val mode: ShowLocationMode) : NavTarget
Expand Down Expand Up @@ -227,17 +229,18 @@ class MessagesFlowNode(
callback.navigateToRoomDetails()
}

override fun handleEventClick(timelineMode: Timeline.Mode, event: TimelineItem.Event): Boolean {
override fun handleEventClick(timelineMode: Timeline.Mode, event: TimelineItem.Event, galleryItemIndex: Int?): Boolean {
return processEventClick(
timelineMode = timelineMode,
event = event,
galleryItemIndex = galleryItemIndex,
)
}

override fun navigateToPreviewAttachments(attachments: ImmutableList<Attachment>, inReplyToEventId: EventId?) {
backstack.push(
NavTarget.AttachmentPreview(
attachment = attachments.first(),
attachments = attachments,
timelineMode = Timeline.Mode.Live,
inReplyToEventId = inReplyToEventId,
)
Expand Down Expand Up @@ -317,6 +320,7 @@ class MessagesFlowNode(
mediaSource = navTarget.mediaSource,
thumbnailSource = navTarget.thumbnailSource,
canShowInfo = true,
galleryItems = navTarget.galleryItems,
)
val callback = object : MediaViewerEntryPoint.Callback {
override fun onDone() {
Expand All @@ -341,7 +345,7 @@ class MessagesFlowNode(
}
is NavTarget.AttachmentPreview -> {
val inputs = AttachmentsPreviewNode.Inputs(
attachment = navTarget.attachment,
attachments = navTarget.attachments,
timelineMode = navTarget.timelineMode,
inReplyToEventId = navTarget.inReplyToEventId,
)
Expand Down Expand Up @@ -456,17 +460,18 @@ class MessagesFlowNode(
focusedEventId = navTarget.focusedEventId,
)
val callback = object : ThreadedMessagesNode.Callback {
override fun handleEventClick(timelineMode: Timeline.Mode, event: TimelineItem.Event): Boolean {
override fun handleEventClick(timelineMode: Timeline.Mode, event: TimelineItem.Event, galleryItemIndex: Int?): Boolean {
return processEventClick(
timelineMode = timelineMode,
event = event,
galleryItemIndex = galleryItemIndex,
)
}

override fun navigateToPreviewAttachments(attachments: ImmutableList<Attachment>, inReplyToEventId: EventId?) {
backstack.push(
NavTarget.AttachmentPreview(
attachment = attachments.first(),
attachments = attachments,
timelineMode = Timeline.Mode.Thread(navTarget.threadRootId),
inReplyToEventId = inReplyToEventId,
)
Expand Down Expand Up @@ -547,6 +552,7 @@ class MessagesFlowNode(
private fun processEventClick(
timelineMode: Timeline.Mode,
event: TimelineItem.Event,
galleryItemIndex: Int? = null,
): Boolean {
val navTarget = when (event.content) {
is TimelineItemImageContent -> {
Expand Down Expand Up @@ -599,6 +605,58 @@ class MessagesFlowNode(
}
NavTarget.LocationViewer(mode = mode).takeIf { locationService.isServiceAvailable() }
}
is TimelineItemGalleryContent -> {
val item = if (galleryItemIndex != null) {
event.content.items.getOrNull(galleryItemIndex)
} else {
event.content.items.firstOrNull()
} ?: return false
val mediaInfo = MediaInfo(
filename = item.filename,
fileSize = null,
caption = event.content.caption,
mimeType = item.mimeType,
formattedFileSize = "",
fileExtension = item.filename.substringAfterLast('.', ""),
senderId = event.senderId,
senderName = event.safeSenderName,
senderAvatar = event.senderAvatar.url,
dateSent = dateFormatter.format(
event.sentTimeMillis,
mode = DateFormatterMode.Day,
),
dateSentFull = dateFormatter.format(
timestamp = event.sentTimeMillis,
mode = DateFormatterMode.Full,
),
waveform = null,
duration = null,
)
val galleryItems = event.content.items.map { galleryItem ->
io.element.android.libraries.mediaviewer.api.GalleryItemData(
filename = galleryItem.filename,
mimeType = galleryItem.mimeType,
mediaSource = galleryItem.mediaSource,
thumbnailSource = galleryItem.thumbnailSource,
isVideo = galleryItem.isVideo,
isAudio = galleryItem.isAudio,
isFile = galleryItem.isFile,
)
}
val mode = if (event.content.items.any { it.isVideo || (!it.isAudio && !it.isFile) }) {
MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos(timelineMode)
} else {
MediaViewerEntryPoint.MediaViewerMode.TimelineFilesAndAudios(timelineMode)
}
NavTarget.MediaViewer(
mode = mode,
eventId = event.eventId,
mediaInfo = mediaInfo,
mediaSource = item.mediaSource,
thumbnailSource = item.thumbnailSource,
galleryItems = galleryItems,
)
}
else -> null
}
return when (navTarget) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class MessagesNode(
)

interface Callback : Plugin {
fun handleEventClick(timelineMode: Timeline.Mode, event: TimelineItem.Event): Boolean
fun handleEventClick(timelineMode: Timeline.Mode, event: TimelineItem.Event, galleryItemIndex: Int? = null): Boolean
fun navigateToPreviewAttachments(attachments: ImmutableList<Attachment>, inReplyToEventId: EventId?)
fun navigateToRoomMemberDetails(userId: UserId)
fun handlePermalinkClick(data: PermalinkData)
Expand Down Expand Up @@ -278,6 +278,18 @@ class MessagesNode(
}
}
},
onGalleryItemClick = { isLive, event, index ->
if (isLive) {
callback.handleEventClick(timelineController.mainTimelineMode(), event, index)
} else {
val detachedTimelineMode = timelineController.detachedTimelineMode()
if (detachedTimelineMode != null) {
callback.handleEventClick(detachedTimelineMode, event, index)
} else {
false
}
}
},
onUserDataClick = callback::navigateToRoomMemberDetails,
onLinkClick = { url, customTab ->
onLinkClick(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ fun MessagesView(
onBackClick: () -> Unit,
onRoomDetailsClick: () -> Unit,
onEventContentClick: (isLive: Boolean, event: TimelineItem.Event) -> Boolean,
onGalleryItemClick: ((isLive: Boolean, event: TimelineItem.Event, index: Int) -> Boolean)? = null,
onUserDataClick: (UserId) -> Unit,
onLinkClick: (String, Boolean) -> Unit,
onSendLocationClick: () -> Unit,
Expand Down Expand Up @@ -256,6 +257,15 @@ fun MessagesView(
MessagesViewContent(
state = state,
onContentClick = ::onContentClick,
onGalleryItemClick = { evt, idx ->
Timber.v("onGalleryItemClick= ${evt.id} index=$idx")
val isLive = state.timelineState.isLive
val handledByGallery = onGalleryItemClick?.invoke(isLive, evt, idx)
val hideKeyboard = handledByGallery ?: onEventContentClick(isLive, evt)
if (hideKeyboard) {
localView.hideKeyboard()
}
},
onMessageLongClick = ::onMessageLongClick,
onUserDataClick = {
hidingKeyboard {
Expand Down Expand Up @@ -451,6 +461,7 @@ private fun ReinviteDialog(state: MessagesState) {
private fun MessagesViewContent(
state: MessagesState,
onContentClick: (TimelineItem.Event) -> Unit,
onGalleryItemClick: ((TimelineItem.Event, Int) -> Unit)? = null,
onUserDataClick: (MatrixUser) -> Unit,
onLinkClick: (Link, Boolean) -> Unit,
onReactionClick: (key: String, TimelineItem.Event) -> Unit,
Expand Down Expand Up @@ -510,6 +521,7 @@ private fun MessagesViewContent(
onUserDataClick = onUserDataClick,
onLinkClick = { link -> onLinkClick(link, false) },
onContentClick = onContentClick,
onGalleryItemClick = onGalleryItemClick,
onMessageLongClick = onMessageLongClick,
onSwipeToReply = onSwipeToReply,
onReactionClick = onReactionClick,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ import io.element.android.features.messages.impl.timeline.a11y.a11yReactionActio
import io.element.android.features.messages.impl.timeline.components.MessageShieldView
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAttachmentsContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemGalleryContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLegacyCallInviteContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContent
Expand Down Expand Up @@ -298,6 +300,12 @@ private fun MessageSummary(
is TimelineItemImageContent -> {
content = { ContentForBody(event.content.bestDescription) }
}
is TimelineItemGalleryContent -> {
content = { ContentForBody(event.content.body) }
}
is TimelineItemAttachmentsContent -> {
content = { ContentForBody(event.content.body) }
}
is TimelineItemStickerContent -> {
content = { ContentForBody(event.content.bestDescription) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.mediaviewer.api.local.LocalMediaRenderer
import kotlinx.collections.immutable.ImmutableList

@ContributesNode(RoomScope::class)
@AssistedInject
Expand All @@ -42,7 +43,7 @@ class AttachmentsPreviewNode(
private val enterpriseService: EnterpriseService,
) : Node(buildContext, plugins = plugins) {
data class Inputs(
val attachment: Attachment,
val attachments: ImmutableList<Attachment>,
val timelineMode: Timeline.Mode,
val inReplyToEventId: EventId?,
) : NodeInputs
Expand All @@ -54,7 +55,7 @@ class AttachmentsPreviewNode(
}

private val presenter = presenterFactory.create(
attachment = inputs.attachment,
attachments = inputs.attachments,
timelineMode = inputs.timelineMode,
onDoneListener = onDoneListener,
inReplyToEventId = inputs.inReplyToEventId,
Expand Down
Loading