Merge pull request #4059 from element-hq/feature/bma/mediaGalleryUpdate
Media gallery update
This commit is contained in:
commit
21d5ff806f
37 changed files with 184 additions and 305 deletions
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9712ec0c9240afdd093e76cbc04143c49807819c31697d957b22e664b66b2dba
|
||||
size 11333
|
||||
oid sha256:8b2613f0382fcc71f248e92a2ab007c20b88178f10f20e91a98f9112ac5dd3b2
|
||||
size 8226
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d5ec1a0bd7a4d1bd06f3b01c960334503ddac208b6cdedf521dea7c0cd83efd2
|
||||
size 15156
|
||||
oid sha256:dfc1ae0e3cb25ee9e6092c2eda4b5e8d03ec3fae37e8d4d4d591e3d697042201
|
||||
size 12845
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:80c113c5a4e71e00e41abc21f22340f8374488047101e4e79472a7549f5bb50f
|
||||
size 38712
|
||||
oid sha256:51c50604b17ac864c548a33141aba6bf9c1c791790a11fe692493a9fd3d91fda
|
||||
size 35598
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:71e8ea9b852fc15170b61c283248034404761487091ed6290015f4e9c9ca2d3e
|
||||
size 10919
|
||||
oid sha256:37f2c5ddc5dbf12e9006865a8e0348949e8811e9e3031721d67dcc0b878d00ba
|
||||
size 8011
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:527242ca1b585e76247210f2a000e6511bfbe90b0c8f8eaf850f8318b6067d5a
|
||||
size 14627
|
||||
oid sha256:a9e21c6ef5aeb835cee91a073ccd23a9fae1f3a1e6bc5c5dfdbe80ce9da62c51
|
||||
size 12496
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a0c1c64b768ec3491200e38b93ff558873d130a3a5c71b8bd5c3f4a49e3d9137
|
||||
size 37273
|
||||
oid sha256:04c3a63bd1d6b1c217946fd3ac359ebbedd33d39da663b489397a4a81744c75d
|
||||
size 34365
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:421bd0bd141a6f6b38ce938c68cb21672b1d3c9cbb83e8cd44fe47bbc2488c3f
|
||||
size 11168
|
||||
oid sha256:9fe856f45857f420a42562f0618473857eccd3f9a16c75df43157b881d473fd4
|
||||
size 8892
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c94c521f50f3b8d2fc5e03365e54e8582ee48d31a47146abfb34cc41972fd38b
|
||||
size 15539
|
||||
oid sha256:fc84a1980024331be4906d1df8702ba16cfee553d18c3556d6c08597cc5c1a05
|
||||
size 13243
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3a8d98c3b6bd629ca6318fb7ac8d989960bf2bb952a9719a305568864d3bbb77
|
||||
size 38554
|
||||
oid sha256:538d13a4aba7f8d7e503852eed6ae2fe35c1a54002c33abe7ef763052d4c7ab8
|
||||
size 36254
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:00f111de4ffa63cfb0cc047ea017a2e740f52a9d0786fadf379937c12ae0e199
|
||||
size 10715
|
||||
oid sha256:674d480011c737b98adc471bca330182efc6eb31b1671e6bdd6aa54bfeaada9d
|
||||
size 8616
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2637ec2e1303341c473cb9380c18fb7c7c1558c1dbd39dcff8d71744e4c3f5c9
|
||||
size 14901
|
||||
oid sha256:3ffaef3911f91499e4905e0d041c8ff31a6343c2b71ea79f0b4ab6d6c89800d5
|
||||
size 12795
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:57b058e64c8361a70492056a09d13e87c4e1b61fbfe785198282d035d27326ac
|
||||
size 37041
|
||||
oid sha256:b2f88af6da9f62f2fe0fb17883387574eaeca5d1f65f651d970e13c22ca8079b
|
||||
size 34947
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8d5d02d56e050717a767bcf12d9da7c6ccf1207bedba0a7ec8b0451a668739d9
|
||||
size 11032
|
||||
oid sha256:9d0b3f44a9a0ed9ab16192b23ccf95b7d34abccd025bb4a7ccd8ebb7a9379965
|
||||
size 10824
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:979326f2383611db2b1ffa8a2a9d0f2a4fb3296fa57a1240daa97ccf36d886e3
|
||||
size 10279
|
||||
oid sha256:73fecb12c33892a9bea41e5a4bbbf4db43990e44b2a36b96d03d7a81046c8f92
|
||||
size 10076
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b799d6bed5f1648f1a5196a1c4ccc1a8f8ed49f3eeb5971bd7c342518a1c8ec3
|
||||
size 10852
|
||||
oid sha256:8f09ea644568c7ab55f0cfc3b8148d8e7821313852cc3fcd78dca2b473a07555
|
||||
size 10871
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:28ead44aa94f2403c4273f38185f0eb21fd9645918829298aee52f9c8061ac95
|
||||
size 13003
|
||||
oid sha256:a45e80573b7db0c47cbe9048c1bb95d66e4b8437dd4816cf6cb3548305549715
|
||||
size 13017
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ae77a7b1bb730842ff0f9608900188d5da78717476f10fb8b640a9c413bf4249
|
||||
size 38548
|
||||
oid sha256:339a6ae86094fb3d0b99d6ea3b23bed14adf7bbe90bc55613d6ece3356f7be16
|
||||
size 38566
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:88df6cf8d0a0ca3ae5cdc0e67a21e0c2da793cc88d65fc780830678f5d5f2f24
|
||||
size 9218
|
||||
oid sha256:19b6feb0228df79d7f6ec505a8b073852e4400366027d93feb61c09186494ac6
|
||||
size 9228
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6dd8d2b4e7d18e3091ac8aca92b8ceb9db6ae15bd228b7a6ce268ed2f7852a53
|
||||
size 10113
|
||||
oid sha256:b7fdc491e73aa3fe1afb52ac6a22b3ced09c73573dc175c415d116293c04c95d
|
||||
size 10129
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c711dea48e04cc05c243541ad48e6ed576b5f225ceecb515d49d08c2b2db5e0f
|
||||
size 12289
|
||||
oid sha256:f816378db978ff00cd722fd44b8219b6181d9cc6fbf4d3b31fea33430e37580e
|
||||
size 12309
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:64f8121851420451628e215393f0835597ea82a67fb2365da2454d52f375bde2
|
||||
size 36802
|
||||
oid sha256:a0b97a65622307f289695d3a19aa0957fe739d35070b1f0cd972f7ff51987a7d
|
||||
size 36824
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:80885e7fa1a8b84e1629f64eb4890079d8f4b556c91b415716616ed2d27e5924
|
||||
size 8589
|
||||
oid sha256:8b71ca3fcc1f94d89264f3d5c5751f46681014b662bcf7d910263dfb23178e0f
|
||||
size 8623
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a6c04486280ce42c65486d4c532c20521f0d03419f1ab042dc61c0b5ff1060c2
|
||||
size 18242
|
||||
oid sha256:873e124ea0560fe577b93b5e55e959baf443eedcb07d6b229f0370621ee0dbf3
|
||||
size 20621
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f8d549d3ef133c621c9e223a3f02f351d8626aeb7b4b05180c2d76b85004cfb9
|
||||
size 39459
|
||||
oid sha256:c8b23c6c8f47f7e49cdb56098408873aa9d3f02af22cae01add580f0e623678d
|
||||
size 34814
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7b332b50ff448deea9bb3fc0db047b99743bb16c730a9ef3dbb203b7ca8982dc
|
||||
size 17067
|
||||
oid sha256:f7c98ab469dd76beea196cfceff2ea9f72c9225f15b701ab7965b54cc9064dd8
|
||||
size 19505
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:742abcea0455c0628bbdd2e2cd3367d7a9431fe00cfa0c657a1a95e83c8a7cbf
|
||||
size 37334
|
||||
oid sha256:e361247dd137a828f1170fc1497ace365e04bb551edcd4984c26b15c26fe65f1
|
||||
size 33011
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue