Merge pull request #4059 from element-hq/feature/bma/mediaGalleryUpdate
Media gallery update
This commit is contained in:
@@ -104,7 +104,6 @@ class EventItemFactory @Inject constructor(
|
||||
waveform = null,
|
||||
),
|
||||
mediaSource = type.source,
|
||||
duration = type.info?.duration?.inWholeMilliseconds?.toHumanReadableDuration(),
|
||||
)
|
||||
is FileMessageType -> MediaItem.File(
|
||||
id = currentTimelineItem.uniqueId,
|
||||
|
||||
@@ -34,7 +34,6 @@ import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -73,7 +72,6 @@ import io.element.android.libraries.mediaviewer.impl.gallery.ui.VideoItemView
|
||||
import io.element.android.libraries.mediaviewer.impl.gallery.ui.VoiceItemView
|
||||
import io.element.android.libraries.voiceplayer.api.VoiceMessageState
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlin.math.max
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -266,44 +264,46 @@ private fun MediaGalleryFilesList(
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
) {
|
||||
items(files) { item ->
|
||||
items(
|
||||
items = files,
|
||||
key = { it.id() },
|
||||
contentType = { it::class.java },
|
||||
) { item ->
|
||||
when (item) {
|
||||
is MediaItem.File -> FileItemView(
|
||||
item,
|
||||
modifier = Modifier.animateItem(),
|
||||
file = item,
|
||||
onClick = { onItemClick(item) },
|
||||
onShareClick = { eventSink(MediaGalleryEvents.Share(item)) },
|
||||
onDownloadClick = { eventSink(MediaGalleryEvents.SaveOnDisk(item)) },
|
||||
onInfoClick = { eventSink(MediaGalleryEvents.OpenInfo(item)) },
|
||||
)
|
||||
is MediaItem.Audio -> AudioItemView(
|
||||
item,
|
||||
modifier = Modifier.animateItem(),
|
||||
audio = item,
|
||||
onClick = { onItemClick(item) },
|
||||
onShareClick = { eventSink(MediaGalleryEvents.Share(item)) },
|
||||
onDownloadClick = { eventSink(MediaGalleryEvents.SaveOnDisk(item)) },
|
||||
onInfoClick = { eventSink(MediaGalleryEvents.OpenInfo(item)) },
|
||||
)
|
||||
is MediaItem.Voice -> {
|
||||
val presenter: Presenter<VoiceMessageState> = presenterFactories.rememberPresenter(item)
|
||||
VoiceItemView(
|
||||
presenter.present(),
|
||||
item,
|
||||
modifier = Modifier.animateItem(),
|
||||
state = presenter.present(),
|
||||
voice = item,
|
||||
onShareClick = { eventSink(MediaGalleryEvents.Share(item)) },
|
||||
onDownloadClick = { eventSink(MediaGalleryEvents.SaveOnDisk(item)) },
|
||||
onInfoClick = { eventSink(MediaGalleryEvents.OpenInfo(item)) },
|
||||
)
|
||||
}
|
||||
is MediaItem.DateSeparator -> DateItemView(item)
|
||||
is MediaItem.DateSeparator -> DateItemView(
|
||||
modifier = Modifier.animateItem(),
|
||||
item = item
|
||||
)
|
||||
is MediaItem.Image,
|
||||
is MediaItem.Video -> {
|
||||
// Should not happen
|
||||
}
|
||||
is MediaItem.LoadingIndicator -> {
|
||||
LoadingMoreIndicator(item.direction)
|
||||
val latestEventSink by rememberUpdatedState(eventSink)
|
||||
LaunchedEffect(item.timestamp) {
|
||||
latestEventSink(MediaGalleryEvents.LoadMore(item.direction))
|
||||
}
|
||||
}
|
||||
is MediaItem.LoadingIndicator -> LoadingMoreIndicator(
|
||||
modifier = Modifier.animateItem(),
|
||||
item = item,
|
||||
eventSink = eventSink,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -315,28 +315,20 @@ private fun MediaGalleryImageGrid(
|
||||
eventSink: (MediaGalleryEvents) -> Unit,
|
||||
onItemClick: (MediaItem.Event) -> Unit,
|
||||
) {
|
||||
val configuration = LocalConfiguration.current
|
||||
val screenWidth = configuration.screenWidthDp.dp
|
||||
val horizontalPadding = 16.dp
|
||||
val itemSpacing = 4.dp
|
||||
val availableWidth = screenWidth - horizontalPadding * 2
|
||||
val minCellWidth = 80.dp
|
||||
// Calculate the number of columns
|
||||
val columns = max(1, (availableWidth / (minCellWidth + itemSpacing)).toInt())
|
||||
LazyVerticalGrid(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = horizontalPadding),
|
||||
columns = GridCells.Fixed(columns),
|
||||
.padding(horizontal = 16.dp),
|
||||
columns = GridCells.Adaptive(80.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
items(
|
||||
imagesAndVideos,
|
||||
items = imagesAndVideos,
|
||||
span = { item ->
|
||||
when (item) {
|
||||
is MediaItem.LoadingIndicator,
|
||||
is MediaItem.DateSeparator -> GridItemSpan(columns)
|
||||
is MediaItem.DateSeparator -> GridItemSpan(maxLineSpan)
|
||||
is MediaItem.Event -> GridItemSpan(1)
|
||||
}
|
||||
},
|
||||
@@ -344,9 +336,10 @@ private fun MediaGalleryImageGrid(
|
||||
contentType = { it::class.java },
|
||||
) { item ->
|
||||
when (item) {
|
||||
is MediaItem.DateSeparator -> {
|
||||
DateItemView(item)
|
||||
}
|
||||
is MediaItem.DateSeparator -> DateItemView(
|
||||
modifier = Modifier.animateItem(),
|
||||
item = item,
|
||||
)
|
||||
is MediaItem.Audio -> {
|
||||
// Should not happen
|
||||
}
|
||||
@@ -356,31 +349,27 @@ private fun MediaGalleryImageGrid(
|
||||
is MediaItem.File -> {
|
||||
// Should not happen
|
||||
}
|
||||
is MediaItem.Image -> {
|
||||
ImageItemView(
|
||||
image = item,
|
||||
onClick = { onItemClick(item) },
|
||||
onLongClick = {
|
||||
eventSink(MediaGalleryEvents.OpenInfo(item))
|
||||
},
|
||||
)
|
||||
}
|
||||
is MediaItem.Video -> {
|
||||
VideoItemView(
|
||||
video = item,
|
||||
onClick = { onItemClick(item) },
|
||||
onLongClick = {
|
||||
eventSink(MediaGalleryEvents.OpenInfo(item))
|
||||
},
|
||||
)
|
||||
}
|
||||
is MediaItem.LoadingIndicator -> {
|
||||
LoadingMoreIndicator(item.direction)
|
||||
val latestEventSink by rememberUpdatedState(eventSink)
|
||||
LaunchedEffect(item.timestamp) {
|
||||
latestEventSink(MediaGalleryEvents.LoadMore(item.direction))
|
||||
}
|
||||
}
|
||||
is MediaItem.Image -> ImageItemView(
|
||||
modifier = Modifier.animateItem(),
|
||||
image = item,
|
||||
onClick = { onItemClick(item) },
|
||||
onLongClick = {
|
||||
eventSink(MediaGalleryEvents.OpenInfo(item))
|
||||
},
|
||||
)
|
||||
is MediaItem.Video -> VideoItemView(
|
||||
modifier = Modifier.animateItem(),
|
||||
video = item,
|
||||
onClick = { onItemClick(item) },
|
||||
onLongClick = {
|
||||
eventSink(MediaGalleryEvents.OpenInfo(item))
|
||||
},
|
||||
)
|
||||
is MediaItem.LoadingIndicator -> LoadingMoreIndicator(
|
||||
modifier = Modifier.animateItem(),
|
||||
item = item,
|
||||
eventSink = eventSink,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -388,14 +377,15 @@ private fun MediaGalleryImageGrid(
|
||||
|
||||
@Composable
|
||||
private fun LoadingMoreIndicator(
|
||||
direction: Timeline.PaginationDirection,
|
||||
item: MediaItem.LoadingIndicator,
|
||||
eventSink: (MediaGalleryEvents) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
when (direction) {
|
||||
when (item.direction) {
|
||||
Timeline.PaginationDirection.FORWARDS -> {
|
||||
LinearProgressIndicator(
|
||||
modifier = Modifier
|
||||
@@ -411,6 +401,10 @@ private fun LoadingMoreIndicator(
|
||||
)
|
||||
}
|
||||
}
|
||||
val latestEventSink by rememberUpdatedState(eventSink)
|
||||
LaunchedEffect(item.timestamp) {
|
||||
latestEventSink(MediaGalleryEvents.LoadMore(item.direction))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ sealed interface MediaItem {
|
||||
val eventId: EventId?,
|
||||
val mediaInfo: MediaInfo,
|
||||
val mediaSource: MediaSource,
|
||||
val duration: String?,
|
||||
) : Event
|
||||
|
||||
data class Voice(
|
||||
|
||||
@@ -54,12 +54,12 @@ class MediaItemsPostProcessor @Inject constructor() {
|
||||
when (item) {
|
||||
is MediaItem.Image,
|
||||
is MediaItem.Video -> {
|
||||
imageAndVideoItemsSubList.add(0, item)
|
||||
imageAndVideoItemsSubList.add(item)
|
||||
}
|
||||
is MediaItem.Audio,
|
||||
is MediaItem.Voice,
|
||||
is MediaItem.File -> {
|
||||
fileItemsSublist.add(0, item)
|
||||
fileItemsSublist.add(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ package io.element.android.libraries.mediaviewer.impl.gallery.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
@@ -30,13 +29,11 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.libraries.core.extensions.withBrackets
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.HorizontalDivider
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.IconButton
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.mediaviewer.impl.gallery.MediaItem
|
||||
|
||||
@@ -44,31 +41,24 @@ import io.element.android.libraries.mediaviewer.impl.gallery.MediaItem
|
||||
fun AudioItemView(
|
||||
audio: MediaItem.Audio,
|
||||
onClick: () -> Unit,
|
||||
onShareClick: () -> Unit,
|
||||
onDownloadClick: () -> Unit,
|
||||
onInfoClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 20.dp, start = 16.dp, end = 16.dp),
|
||||
.padding(horizontal = 16.dp),
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
FilenameRow(
|
||||
audio = audio,
|
||||
onClick = onClick,
|
||||
)
|
||||
val caption = audio.mediaInfo.caption
|
||||
if (caption != null) {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Caption(caption)
|
||||
CaptionView(caption)
|
||||
} else {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
}
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
ActionIconsRow(
|
||||
onShareClick = onShareClick,
|
||||
onDownloadClick = onDownloadClick,
|
||||
onInfoClick = onInfoClick,
|
||||
)
|
||||
HorizontalDivider()
|
||||
}
|
||||
}
|
||||
@@ -101,16 +91,6 @@ private fun FilenameRow(
|
||||
imageVector = Icons.Outlined.GraphicEq,
|
||||
contentDescription = null,
|
||||
)
|
||||
audio.duration?.let {
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = audio.duration,
|
||||
style = ElementTheme.typography.fontBodyMdMedium,
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = audio.mediaInfo.filename,
|
||||
@@ -131,55 +111,6 @@ private fun FilenameRow(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Caption(caption: String) {
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = caption,
|
||||
maxLines = 5,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = ElementTheme.typography.fontBodyLgRegular,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ActionIconsRow(
|
||||
onShareClick: () -> Unit,
|
||||
onDownloadClick: () -> Unit,
|
||||
onInfoClick: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.End
|
||||
) {
|
||||
IconButton(
|
||||
onClick = onShareClick,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.ShareAndroid(),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
onClick = onDownloadClick,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.Download(),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
onClick = onInfoClick,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.Info(),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun AudioItemViewPreview(
|
||||
@@ -188,8 +119,5 @@ internal fun AudioItemViewPreview(
|
||||
AudioItemView(
|
||||
audio = audio,
|
||||
onClick = {},
|
||||
onShareClick = {},
|
||||
onDownloadClick = {},
|
||||
onInfoClick = {},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2024 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.mediaviewer.impl.gallery.ui
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
|
||||
@Composable
|
||||
fun CaptionView(
|
||||
caption: String,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Text(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 16.dp),
|
||||
text = caption,
|
||||
maxLines = 5,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = ElementTheme.typography.fontBodyLgRegular,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
)
|
||||
}
|
||||
@@ -9,7 +9,6 @@ package io.element.android.libraries.mediaviewer.impl.gallery.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
@@ -34,7 +33,6 @@ import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.HorizontalDivider
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.IconButton
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.mediaviewer.impl.gallery.MediaItem
|
||||
|
||||
@@ -42,31 +40,24 @@ import io.element.android.libraries.mediaviewer.impl.gallery.MediaItem
|
||||
fun FileItemView(
|
||||
file: MediaItem.File,
|
||||
onClick: () -> Unit,
|
||||
onShareClick: () -> Unit,
|
||||
onDownloadClick: () -> Unit,
|
||||
onInfoClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 20.dp, start = 16.dp, end = 16.dp),
|
||||
.padding(horizontal = 16.dp),
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
FilenameRow(
|
||||
file = file,
|
||||
onClick = onClick,
|
||||
)
|
||||
val caption = file.mediaInfo.caption
|
||||
if (caption != null) {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Caption(caption)
|
||||
CaptionView(caption)
|
||||
} else {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
}
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
ActionIconsRow(
|
||||
onShareClick = onShareClick,
|
||||
onDownloadClick = onDownloadClick,
|
||||
onInfoClick = onInfoClick,
|
||||
)
|
||||
HorizontalDivider()
|
||||
}
|
||||
}
|
||||
@@ -119,55 +110,6 @@ private fun FilenameRow(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Caption(caption: String) {
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = caption,
|
||||
maxLines = 5,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = ElementTheme.typography.fontBodyLgRegular,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ActionIconsRow(
|
||||
onShareClick: () -> Unit,
|
||||
onDownloadClick: () -> Unit,
|
||||
onInfoClick: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.End
|
||||
) {
|
||||
IconButton(
|
||||
onClick = onShareClick,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.ShareAndroid(),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
onClick = onDownloadClick,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.Download(),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
onClick = onInfoClick,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = CompoundIcons.Info(),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun FileItemViewPreview(
|
||||
@@ -176,8 +118,5 @@ internal fun FileItemViewPreview(
|
||||
FileItemView(
|
||||
file = file,
|
||||
onClick = {},
|
||||
onShareClick = {},
|
||||
onDownloadClick = {},
|
||||
onInfoClick = {},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ fun aMediaItemAudio(
|
||||
id: UniqueId = UniqueId("fileId"),
|
||||
filename: String = "filename",
|
||||
caption: String? = null,
|
||||
duration: String? = "1:23",
|
||||
): MediaItem.Audio {
|
||||
return MediaItem.Audio(
|
||||
id = id,
|
||||
@@ -42,6 +41,5 @@ fun aMediaItemAudio(
|
||||
caption = caption,
|
||||
),
|
||||
mediaSource = MediaSource(""),
|
||||
duration = duration,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -66,18 +66,19 @@ fun VoiceItemView(
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 20.dp, start = 16.dp, end = 16.dp),
|
||||
.padding(horizontal = 16.dp),
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
VoiceInfoRow(
|
||||
state = state,
|
||||
voice = voice,
|
||||
)
|
||||
val caption = voice.mediaInfo.caption
|
||||
if (caption != null) {
|
||||
CaptionView(caption)
|
||||
} else {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Caption(caption)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
ActionIconsRow(
|
||||
onShareClick = onShareClick,
|
||||
onDownloadClick = onDownloadClick,
|
||||
@@ -116,7 +117,7 @@ private fun VoiceInfoRow(
|
||||
}
|
||||
Spacer(Modifier.width(8.dp))
|
||||
Text(
|
||||
text = state.time,
|
||||
text = if (state.progress > 0f) state.time else voice.duration ?: state.time,
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
style = ElementTheme.typography.fontBodyMdMedium,
|
||||
maxLines = 1,
|
||||
@@ -256,18 +257,6 @@ private fun CustomIconButton(
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Caption(caption: String) {
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = caption,
|
||||
maxLines = 5,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = ElementTheme.typography.fontBodyLgRegular,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ActionIconsRow(
|
||||
onShareClick: () -> Unit,
|
||||
|
||||
@@ -262,7 +262,6 @@ class DefaultEventItemFactoryTest {
|
||||
waveform = null,
|
||||
),
|
||||
mediaSource = MediaSource(""),
|
||||
duration = "7:36",
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -85,10 +85,10 @@ class MediaItemsPostProcessorTest {
|
||||
expectedImageAndVideoItems = emptyList(),
|
||||
expectedFileItems = listOf(
|
||||
date1,
|
||||
file1,
|
||||
file2,
|
||||
file3,
|
||||
audio1,
|
||||
file3,
|
||||
file2,
|
||||
file1,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -104,9 +104,9 @@ class MediaItemsPostProcessorTest {
|
||||
),
|
||||
expectedImageAndVideoItems = listOf(
|
||||
date1,
|
||||
image1,
|
||||
image2,
|
||||
image3,
|
||||
image2,
|
||||
image1,
|
||||
),
|
||||
expectedFileItems = emptyList(),
|
||||
)
|
||||
@@ -124,13 +124,13 @@ class MediaItemsPostProcessorTest {
|
||||
),
|
||||
expectedImageAndVideoItems = listOf(
|
||||
date1,
|
||||
video1,
|
||||
image1,
|
||||
video1,
|
||||
),
|
||||
expectedFileItems = listOf(
|
||||
date1,
|
||||
file1,
|
||||
audio1,
|
||||
file1,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -167,6 +167,11 @@ class MediaItemsPostProcessorTest {
|
||||
fun `process will handle complex case`() {
|
||||
test(
|
||||
mediaItems = listOf(
|
||||
file3,
|
||||
date3,
|
||||
video3,
|
||||
video2,
|
||||
date2,
|
||||
voice3,
|
||||
voice2,
|
||||
voice1,
|
||||
@@ -177,33 +182,28 @@ class MediaItemsPostProcessorTest {
|
||||
image1,
|
||||
video1,
|
||||
date1,
|
||||
file3,
|
||||
date3,
|
||||
video3,
|
||||
video2,
|
||||
date2,
|
||||
loading1,
|
||||
),
|
||||
expectedImageAndVideoItems = listOf(
|
||||
date1,
|
||||
video1,
|
||||
image1,
|
||||
date2,
|
||||
video2,
|
||||
video3,
|
||||
video2,
|
||||
date1,
|
||||
image1,
|
||||
video1,
|
||||
loading1,
|
||||
),
|
||||
expectedFileItems = listOf(
|
||||
date1,
|
||||
file1,
|
||||
audio1,
|
||||
audio2,
|
||||
audio3,
|
||||
voice1,
|
||||
voice2,
|
||||
voice3,
|
||||
date3,
|
||||
file3,
|
||||
date1,
|
||||
voice3,
|
||||
voice2,
|
||||
voice1,
|
||||
audio3,
|
||||
audio2,
|
||||
audio1,
|
||||
file1,
|
||||
loading1,
|
||||
),
|
||||
)
|
||||
|
||||
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.
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.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user