Merge pull request #4080 from element-hq/feature/bma/galleryLoading
Improve gallery loading state
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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(),
|
||||
),
|
||||
)
|
||||
)
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user