Support gallery messages (#6519)

* Support gallery messages

* Address review

* Remove unused function

* Fix indent

* Add "Gallery" message prefix

* Support galleries for image editing

* Fix tapping on a tile opens the last item

* Fix overflow count

* Add caption editing to gallery messages

* Use the new gallery string for prefix

* Lock sending galleries behind a feature flag

* Fix detekts

* Fix

* Ensure image edition is saved when navigating

* Fix sending media broken on edited gallery.

* Fix tests

* Order imports

* Remove unused parameters.

* Fix copyright header of new files.

* Fix Konsist test

* Extract new previews to a dedicated file.

* Sync strings

* Remove unused import

* Update screenshots

* Trigger CI

* Remove parameters with default value.

* More cleanup

* Restore sendAsFile behavior.

* Improve Preview.

* Improve Preview.

* Improve Preview.

* Fix gallery sending cancel and retry issue

* Ensure any previous job is cancelled.

* Fix issue in summary message

* Gallery feature is disabled by default.

* Kotlin convention

* Remove useless parenthesis

* Update screenshots

* Fix test

* List -> ImmutableList

* Remove useless code.

* Render formatted caption for attachment list.

* Replace set of Booleans by an enum

* Remove unused model for individual caption in a gallery Event.

* Fix tests

* Fix tests

* Rework MediaViewer entry point.

And ensure that the clicked image from the gallery is displayed first.

* Ensure gallery item can be click in the pinned message list
Improve the gallery item click handling code.

* Improve code and fix separator color
Closes #7101

* React on attachment item click
Improve code

* Improve code and support 0 items in gallery.

* Fix click on attachment item not rendering anything.

---------

Co-authored-by: Benoit Marty <benoitm@element.io>
Co-authored-by: Benoit Marty <benoit@matrix.org>
Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
bxdxnn
2026-06-26 17:00:56 +03:00
committed by GitHub
parent 9e7ae34728
commit 87aff40b26
180 changed files with 3470 additions and 637 deletions
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.mediaviewer.api
import android.os.Parcelable
import io.element.android.libraries.matrix.api.media.MediaSource
import kotlinx.parcelize.Parcelize
@Parcelize
data class GalleryItemData(
val filename: String,
val mimeType: String,
val mediaSource: MediaSource,
val thumbnailSource: MediaSource?,
val type: Type,
) : Parcelable {
enum class Type {
Image,
Video,
Audio,
File,
}
}
@@ -13,6 +13,24 @@ import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.matrix.api.core.UserId
import kotlinx.parcelize.Parcelize
@Parcelize
data class GalleryInfo(
val caption: String?,
val formattedCaption: CharSequence? = null,
val senderId: UserId?,
val senderName: String?,
val senderAvatar: String?,
val dateSent: String?,
val dateSentFull: String?,
val initialIndex: Int,
val isAttachment: Boolean,
) : Parcelable
@Parcelize
data class AvatarInfo(
val filename: String,
) : Parcelable
@Parcelize
data class MediaInfo(
val filename: String,
@@ -35,19 +35,29 @@ interface MediaViewerEntryPoint : FeatureEntryPoint {
fun forwardEvent(eventId: EventId, fromPinnedEvents: Boolean)
}
data class Params(
val mode: MediaViewerMode,
val eventId: EventId?,
val mediaInfo: MediaInfo,
val mediaSource: MediaSource,
val thumbnailSource: MediaSource?,
val canShowInfo: Boolean,
) : NodeInputs
sealed interface Params : NodeInputs {
data class RoomMedia(
val mode: MediaViewerMode,
val eventId: EventId?,
val mediaInfo: MediaInfo,
val mediaSource: MediaSource,
val thumbnailSource: MediaSource?,
) : Params
data class EventGallery(
val eventId: EventId?,
val galleryInfo: GalleryInfo,
val galleryItems: List<GalleryItemData>,
) : Params
data class Avatar(
val avatarInfo: AvatarInfo,
val mediaSource: MediaSource,
val thumbnailSource: MediaSource?,
) : Params
}
sealed interface MediaViewerMode : Parcelable {
@Parcelize
data object SingleMedia : MediaViewerMode
@Parcelize
data class TimelineImagesAndVideos(val timelineMode: Timeline.Mode) : MediaViewerMode