Add support for files navigation (when coming from the gallery)

This commit is contained in:
Benoit Marty
2025-01-17 12:19:42 +01:00
committed by Benoit Marty
parent 901ad85ee6
commit 7397dde87d
6 changed files with 34 additions and 7 deletions

View File

@@ -246,6 +246,8 @@ class MessagesFlowNode @AssistedInject constructor(
}
is NavTarget.MediaViewer -> {
val params = MediaViewerEntryPoint.Params(
// TODO When we will be able to load a media timeline from a EventId, change mode here (and use a mixed mode?)
mode = MediaViewerEntryPoint.MediaViewerMode.SingleMedia,
eventId = navTarget.eventId,
mediaInfo = navTarget.mediaInfo,
mediaSource = navTarget.mediaSource,

View File

@@ -31,10 +31,17 @@ interface MediaViewerEntryPoint : FeatureEntryPoint {
}
data class Params(
val mode: MediaViewerMode,
val eventId: EventId?,
val mediaInfo: MediaInfo,
val mediaSource: MediaSource,
val thumbnailSource: MediaSource?,
val canShowInfo: Boolean,
) : NodeInputs
enum class MediaViewerMode {
SingleMedia,
TimelineImagesAndVideos,
TimelineFilesAndAudios,
}
}

View File

@@ -42,6 +42,7 @@ class DefaultMediaViewerEntryPoint @Inject constructor() : MediaViewerEntryPoint
val mimeType = MimeTypes.Images
return params(
MediaViewerEntryPoint.Params(
mode = MediaViewerEntryPoint.MediaViewerMode.SingleMedia,
eventId = null,
mediaInfo = MediaInfo(
filename = filename,

View File

@@ -18,9 +18,8 @@ import io.element.android.libraries.mediaviewer.api.MediaViewerEntryPoint
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.flowOf
import javax.inject.Inject
class SingleMediaGalleryDataSource @Inject constructor(
class SingleMediaGalleryDataSource(
private val data: GroupedMediaItems,
) : MediaGalleryDataSource {
override fun start() = Unit
@@ -91,9 +90,9 @@ class SingleMediaGalleryDataSource @Inject constructor(
}
}
else -> {
// Always use imageAndVideoItems, in Single mode, this is the data that will be used
GroupedMediaItems(
imageAndVideoItems = persistentListOf(),
fileItems = persistentListOf(
imageAndVideoItems = persistentListOf(
MediaItem.File(
id = UniqueId("dummy"),
eventId = params.eventId,
@@ -101,6 +100,7 @@ class SingleMediaGalleryDataSource @Inject constructor(
mediaSource = params.mediaSource,
)
),
fileItems = persistentListOf(),
)
}
}

View File

@@ -60,6 +60,7 @@ class MediaGalleryRootNode @AssistedInject constructor(
@Parcelize
data class MediaViewer(
val mode: MediaViewerEntryPoint.MediaViewerMode,
val eventId: EventId?,
val mediaInfo: MediaInfo,
val mediaSource: MediaSource,
@@ -92,8 +93,16 @@ class MediaGalleryRootNode @AssistedInject constructor(
}
override fun onItemClick(item: MediaItem.Event) {
val mode = when (item) {
is MediaItem.Audio,
is MediaItem.Voice,
is MediaItem.File -> MediaViewerEntryPoint.MediaViewerMode.TimelineFilesAndAudios
is MediaItem.Image,
is MediaItem.Video -> MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos
}
overlay.show(
NavTarget.MediaViewer(
mode = mode,
eventId = item.eventId(),
mediaInfo = item.mediaInfo(),
mediaSource = item.mediaSource(),
@@ -117,6 +126,7 @@ class MediaGalleryRootNode @AssistedInject constructor(
mediaViewerEntryPoint.nodeBuilder(this, buildContext)
.params(
MediaViewerEntryPoint.Params(
mode = navTarget.mode,
eventId = navTarget.eventId,
mediaInfo = navTarget.mediaInfo,
mediaSource = navTarget.mediaSource,

View File

@@ -41,6 +41,7 @@ import io.element.android.libraries.mediaviewer.api.local.LocalMedia
import io.element.android.libraries.mediaviewer.api.local.LocalMediaFactory
import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState
import io.element.android.libraries.mediaviewer.impl.gallery.MediaGalleryDataSource
import io.element.android.libraries.mediaviewer.impl.gallery.MediaGalleryMode
import io.element.android.libraries.mediaviewer.impl.gallery.MediaItem
import io.element.android.libraries.mediaviewer.impl.gallery.eventId
import io.element.android.libraries.mediaviewer.impl.gallery.mediaInfo
@@ -71,6 +72,12 @@ class MediaViewerPresenter @AssistedInject constructor(
): MediaViewerPresenter
}
private val galleryMode = when (inputs.mode) {
MediaViewerEntryPoint.MediaViewerMode.SingleMedia,
MediaViewerEntryPoint.MediaViewerMode.TimelineImagesAndVideos -> MediaGalleryMode.Images
MediaViewerEntryPoint.MediaViewerMode.TimelineFilesAndAudios -> MediaGalleryMode.Files
}
@Composable
override fun present(): MediaViewerState {
val coroutineScope = rememberCoroutineScope()
@@ -93,10 +100,10 @@ class MediaViewerPresenter @AssistedInject constructor(
buildList {
val data = groupedMediaItem.dataOrNull()
if (data != null) {
if (data.imageAndVideoItems.firstOrNull() is MediaItem.LoadingIndicator) {
if (data.getItems(galleryMode).firstOrNull() is MediaItem.LoadingIndicator) {
add(MediaViewerPageData.Loading(Timeline.PaginationDirection.FORWARDS))
}
data.imageAndVideoItems.filterIsInstance<MediaItem.Event>().forEach { mediaItem ->
data.getItems(galleryMode).filterIsInstance<MediaItem.Event>().forEach { mediaItem ->
val eventId = mediaItem.eventId()
add(
MediaViewerPageData.MediaViewerData(
@@ -110,7 +117,7 @@ class MediaViewerPresenter @AssistedInject constructor(
)
)
}
if (data.imageAndVideoItems.lastOrNull() is MediaItem.LoadingIndicator) {
if (data.getItems(galleryMode).lastOrNull() is MediaItem.LoadingIndicator) {
add(MediaViewerPageData.Loading(Timeline.PaginationDirection.BACKWARDS))
}
}