This commit is contained in:
Benoit Marty 2025-01-28 11:33:07 +01:00
parent fdf40120a7
commit e9a9e79b40
7 changed files with 31 additions and 54 deletions

View file

@ -39,7 +39,6 @@ interface MediaViewerEntryPoint : FeatureEntryPoint {
val canShowInfo: Boolean, val canShowInfo: Boolean,
) : NodeInputs ) : NodeInputs
// TODO convert to sealed class and add eventId to the 2nd and 3rd items
enum class MediaViewerMode { enum class MediaViewerMode {
SingleMedia, SingleMedia,
TimelineImagesAndVideos, TimelineImagesAndVideos,

View file

@ -50,7 +50,7 @@ class TimelineMediaGalleryDataSource @Inject constructor(
override fun groupedMediaItemsFlow(): Flow<AsyncData<GroupedMediaItems>> = groupedMediaItemsFlow override fun groupedMediaItemsFlow(): Flow<AsyncData<GroupedMediaItems>> = groupedMediaItemsFlow
override fun getLastData(): AsyncData<GroupedMediaItems> = groupedMediaItemsFlow.replayCache.firstOrNull() override fun getLastData(): AsyncData<GroupedMediaItems> = groupedMediaItemsFlow.replayCache.firstOrNull()
?: mediaTimeline.getCache()?.let { AsyncData.Success(it) } ?: mediaTimeline.cache?.let { AsyncData.Success(it) }
?: AsyncData.Uninitialized ?: AsyncData.Uninitialized
private val isStarted = AtomicBoolean(false) private val isStarted = AtomicBoolean(false)
@ -61,7 +61,7 @@ class TimelineMediaGalleryDataSource @Inject constructor(
return return
} }
flow { flow {
val cache = mediaTimeline.getCache() val cache = mediaTimeline.cache
if (cache != null) { if (cache != null) {
groupedMediaItemsFlow.emit(AsyncData.Success(cache)) groupedMediaItemsFlow.emit(AsyncData.Success(cache))
} else { } else {

View file

@ -9,6 +9,7 @@ package io.element.android.libraries.mediaviewer.impl.gallery
import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.mediaviewer.impl.R import io.element.android.libraries.mediaviewer.impl.R
import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState import io.element.android.libraries.mediaviewer.impl.details.MediaBottomSheetState
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
@ -34,6 +35,12 @@ data class GroupedMediaItems(
} }
} }
fun GroupedMediaItems.hasEvent(eventId: EventId): Boolean {
return (fileItems + imageAndVideoItems)
.filterIsInstance<MediaItem.Event>()
.any { it.eventId() == eventId }
}
enum class MediaGalleryMode(val stringResource: Int) { enum class MediaGalleryMode(val stringResource: Int) {
Images(R.string.screen_media_browser_list_mode_media), Images(R.string.screen_media_browser_list_mode_media),
Files(R.string.screen_media_browser_list_mode_files), Files(R.string.screen_media_browser_list_mode_files),

View file

@ -440,10 +440,7 @@ private fun LoadingMoreIndicator(
} }
val latestEventSink by rememberUpdatedState(eventSink) val latestEventSink by rememberUpdatedState(eventSink)
LaunchedEffect(item.timestamp) { LaunchedEffect(item.timestamp) {
// TODO Add isFake to the model instead of using -1 for timestamp latestEventSink(MediaGalleryEvents.LoadMore(item.direction))
if (item.timestamp != -1L) {
latestEventSink(MediaGalleryEvents.LoadMore(item.direction))
}
} }
} }
} }

View file

@ -19,7 +19,7 @@ import javax.inject.Inject
interface MediaTimeline { interface MediaTimeline {
suspend fun getTimeline(): Result<Timeline> suspend fun getTimeline(): Result<Timeline>
fun getCache(): GroupedMediaItems? val cache: GroupedMediaItems?
fun orCache(data: GroupedMediaItems): GroupedMediaItems fun orCache(data: GroupedMediaItems): GroupedMediaItems
} }
@ -51,7 +51,7 @@ class LiveMediaTimeline @Inject constructor(
} }
// No cache for LiveMediaTimeline // No cache for LiveMediaTimeline
override fun getCache(): GroupedMediaItems? = null override val cache = null
override fun orCache(data: GroupedMediaItems) = data override fun orCache(data: GroupedMediaItems) = data
} }
@ -61,41 +61,28 @@ class LiveMediaTimeline @Inject constructor(
class FocusedMediaTimeline( class FocusedMediaTimeline(
private val room: MatrixRoom, private val room: MatrixRoom,
private val eventId: EventId, private val eventId: EventId,
private val initialMediaItem: MediaItem.Event, initialMediaItem: MediaItem.Event,
) : MediaTimeline { ) : MediaTimeline {
override suspend fun getTimeline(): Result<Timeline> { override suspend fun getTimeline(): Result<Timeline> {
return room.mediaTimeline(eventId) return room.mediaTimeline(eventId)
} }
override fun getCache(): GroupedMediaItems { override val cache = persistentListOf(
// TODO Cleanup MediaItem.LoadingIndicator(
return GroupedMediaItems( id = UniqueId("loading_forwards"),
fileItems = persistentListOf( direction = Timeline.PaginationDirection.FORWARDS,
MediaItem.LoadingIndicator( timestamp = 0L,
id = UniqueId("loading_forwards"), ),
direction = Timeline.PaginationDirection.FORWARDS, initialMediaItem,
timestamp = -1L, MediaItem.LoadingIndicator(
), id = UniqueId("loading_backwards"),
initialMediaItem, direction = Timeline.PaginationDirection.BACKWARDS,
MediaItem.LoadingIndicator( timestamp = 0L,
id = UniqueId("loading_backwards"), ),
direction = Timeline.PaginationDirection.BACKWARDS, ).let {
timestamp = -1L, GroupedMediaItems(
), fileItems = it,
), imageAndVideoItems = it,
imageAndVideoItems = persistentListOf(
MediaItem.LoadingIndicator(
id = UniqueId("loading_forwards"),
direction = Timeline.PaginationDirection.FORWARDS,
timestamp = -1L,
),
initialMediaItem,
MediaItem.LoadingIndicator(
id = UniqueId("loading_backwards"),
direction = Timeline.PaginationDirection.BACKWARDS,
timestamp = -1L,
),
),
) )
} }
@ -103,13 +90,7 @@ class FocusedMediaTimeline(
return if (data.hasEvent(eventId)) { return if (data.hasEvent(eventId)) {
data data
} else { } else {
getCache() cache
} }
} }
} }
fun GroupedMediaItems.hasEvent(eventId: EventId): Boolean {
return (fileItems + imageAndVideoItems)
.filterIsInstance<MediaItem.Event>()
.any { it.eventId() == eventId }
}

View file

@ -50,11 +50,3 @@ sealed interface MediaViewerPageData {
override val pagerKey: Long, override val pagerKey: Long,
) : MediaViewerPageData ) : MediaViewerPageData
} }
fun MediaViewerPageData.toKey(): String {
return when (this) {
is MediaViewerPageData.Failure -> "Failure"
is MediaViewerPageData.Loading -> "Loading_${direction}"
is MediaViewerPageData.MediaViewerData -> eventId?.value ?: mediaSource.url
}
}

View file

@ -136,6 +136,7 @@ class KonsistClassNameTest {
"Enterprise", "Enterprise",
"Fdroid", "Fdroid",
"FileExtensionExtractor", "FileExtensionExtractor",
"LiveMediaTimeline",
"KeyStore", "KeyStore",
"Matrix", "Matrix",
"Noop", "Noop",