Merge pull request #4080 from element-hq/feature/bma/galleryLoading

Improve gallery loading state
This commit is contained in:
Benoit Marty
2024-12-20 16:40:45 +01:00
committed by GitHub
15 changed files with 112 additions and 53 deletions

View File

@@ -25,7 +25,14 @@ data class MediaGalleryState(
data class GroupedMediaItems(
val imageAndVideoItems: ImmutableList<MediaItem>,
val fileItems: ImmutableList<MediaItem>,
)
) {
fun getItems(mode: MediaGalleryMode): ImmutableList<MediaItem> {
return when (mode) {
MediaGalleryMode.Images -> imageAndVideoItems
MediaGalleryMode.Files -> fileItems
}
}
}
enum class MediaGalleryMode(val stringResource: Int) {
Images(R.string.screen_media_browser_list_mode_media),

View File

@@ -84,6 +84,27 @@ open class MediaGalleryStateProvider : PreviewParameterProvider<MediaGalleryStat
mode = MediaGalleryMode.Files,
groupedMediaItems = AsyncData.Failure(Exception("Failed to load media")),
),
// Timeline is loaded but does not have relevant content yet for images and videos
aMediaGalleryState(
groupedMediaItems = AsyncData.Success(
aGroupedMediaItems(
imageAndVideoItems = listOf(
aMediaItemLoadingIndicator(),
),
)
)
),
// Timeline is loaded but does not have relevant content yet for files
aMediaGalleryState(
mode = MediaGalleryMode.Files,
groupedMediaItems = AsyncData.Success(
aGroupedMediaItems(
fileItems = listOf(
aMediaItemLoadingIndicator(),
),
)
)
),
)
}

View File

@@ -196,30 +196,44 @@ private fun MediaGalleryPage(
state: MediaGalleryState,
onItemClick: (MediaItem.Event) -> Unit,
) {
when (val groupedMediaItems = state.groupedMediaItems) {
AsyncData.Uninitialized,
is AsyncData.Loading -> {
LoadingContent(mode)
}
is AsyncData.Success -> {
when (mode) {
MediaGalleryMode.Images -> MediaGalleryImages(
imagesAndVideos = groupedMediaItems.data.imageAndVideoItems,
eventSink = state.eventSink,
onItemClick = onItemClick,
)
MediaGalleryMode.Files -> MediaGalleryFiles(
files = groupedMediaItems.data.fileItems,
eventSink = state.eventSink,
onItemClick = onItemClick,
val groupedMediaItems = state.groupedMediaItems
if (groupedMediaItems.isLoadingItems(mode)) {
LoadingContent(mode)
} else {
when (groupedMediaItems) {
is AsyncData.Success -> {
when (mode) {
MediaGalleryMode.Images -> MediaGalleryImages(
imagesAndVideos = groupedMediaItems.data.imageAndVideoItems,
eventSink = state.eventSink,
onItemClick = onItemClick,
)
MediaGalleryMode.Files -> MediaGalleryFiles(
files = groupedMediaItems.data.fileItems,
eventSink = state.eventSink,
onItemClick = onItemClick,
)
}
}
is AsyncData.Failure -> {
ErrorContent(
error = groupedMediaItems.error,
)
}
else -> Unit
}
is AsyncData.Failure -> {
ErrorContent(
error = groupedMediaItems.error,
)
}
}
}
/**
* Return true when the timeline is not loaded or if it contains only a single loading item.
*/
private fun AsyncData<GroupedMediaItems>.isLoadingItems(mode: MediaGalleryMode): Boolean {
return when (this) {
AsyncData.Uninitialized,
is AsyncData.Loading -> true
is AsyncData.Success -> data.getItems(mode).singleOrNull() is MediaItem.LoadingIndicator
is AsyncData.Failure -> false
}
}
@@ -460,23 +474,28 @@ private fun EmptyContent(
private fun LoadingContent(
mode: MediaGalleryMode,
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(top = 48.dp)
.padding(24.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
Box(
modifier = Modifier.fillMaxSize(),
) {
CircularProgressIndicator()
val res = when (mode) {
MediaGalleryMode.Images -> R.string.screen_media_browser_list_loading_media
MediaGalleryMode.Files -> R.string.screen_media_browser_list_loading_files
OnboardingBackground()
Column(
modifier = Modifier
.fillMaxSize()
.padding(top = 48.dp)
.padding(24.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
CircularProgressIndicator()
val res = when (mode) {
MediaGalleryMode.Images -> R.string.screen_media_browser_list_loading_media
MediaGalleryMode.Files -> R.string.screen_media_browser_list_loading_files
}
Text(
text = stringResource(res),
modifier = Modifier.align(Alignment.CenterHorizontally),
)
}
Text(
text = stringResource(res),
modifier = Modifier.align(Alignment.CenterHorizontally),
)
}
}