Gallery: Actions on files are actually only for voice messages.

This commit is contained in:
Benoit Marty 2024-12-17 16:21:26 +01:00
parent 0786c135cd
commit 960154b741
9 changed files with 52 additions and 173 deletions

View file

@ -104,7 +104,6 @@ class EventItemFactory @Inject constructor(
waveform = null, waveform = null,
), ),
mediaSource = type.source, mediaSource = type.source,
duration = type.info?.duration?.inWholeMilliseconds?.toHumanReadableDuration(),
) )
is FileMessageType -> MediaItem.File( is FileMessageType -> MediaItem.File(
id = currentTimelineItem.uniqueId, id = currentTimelineItem.uniqueId,

View file

@ -267,24 +267,18 @@ private fun MediaGalleryFilesList(
items(files) { item -> items(files) { item ->
when (item) { when (item) {
is MediaItem.File -> FileItemView( is MediaItem.File -> FileItemView(
item, file = item,
onClick = { onItemClick(item) }, onClick = { onItemClick(item) },
onShareClick = { eventSink(MediaGalleryEvents.Share(item)) },
onDownloadClick = { eventSink(MediaGalleryEvents.SaveOnDisk(item)) },
onInfoClick = { eventSink(MediaGalleryEvents.OpenInfo(item)) },
) )
is MediaItem.Audio -> AudioItemView( is MediaItem.Audio -> AudioItemView(
item, audio = item,
onClick = { onItemClick(item) }, onClick = { onItemClick(item) },
onShareClick = { eventSink(MediaGalleryEvents.Share(item)) },
onDownloadClick = { eventSink(MediaGalleryEvents.SaveOnDisk(item)) },
onInfoClick = { eventSink(MediaGalleryEvents.OpenInfo(item)) },
) )
is MediaItem.Voice -> { is MediaItem.Voice -> {
val presenter: Presenter<VoiceMessageState> = presenterFactories.rememberPresenter(item) val presenter: Presenter<VoiceMessageState> = presenterFactories.rememberPresenter(item)
VoiceItemView( VoiceItemView(
presenter.present(), state = presenter.present(),
item, voice = item,
onShareClick = { eventSink(MediaGalleryEvents.Share(item)) }, onShareClick = { eventSink(MediaGalleryEvents.Share(item)) },
onDownloadClick = { eventSink(MediaGalleryEvents.SaveOnDisk(item)) }, onDownloadClick = { eventSink(MediaGalleryEvents.SaveOnDisk(item)) },
onInfoClick = { eventSink(MediaGalleryEvents.OpenInfo(item)) }, onInfoClick = { eventSink(MediaGalleryEvents.OpenInfo(item)) },

View file

@ -57,7 +57,6 @@ sealed interface MediaItem {
val eventId: EventId?, val eventId: EventId?,
val mediaInfo: MediaInfo, val mediaInfo: MediaInfo,
val mediaSource: MediaSource, val mediaSource: MediaSource,
val duration: String?,
) : Event ) : Event
data class Voice( data class Voice(

View file

@ -9,7 +9,6 @@ package io.element.android.libraries.mediaviewer.impl.gallery.ui
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer 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.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme 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.core.extensions.withBrackets
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight 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.HorizontalDivider
import io.element.android.libraries.designsystem.theme.components.Icon 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.designsystem.theme.components.Text
import io.element.android.libraries.mediaviewer.impl.gallery.MediaItem import io.element.android.libraries.mediaviewer.impl.gallery.MediaItem
@ -44,31 +41,24 @@ import io.element.android.libraries.mediaviewer.impl.gallery.MediaItem
fun AudioItemView( fun AudioItemView(
audio: MediaItem.Audio, audio: MediaItem.Audio,
onClick: () -> Unit, onClick: () -> Unit,
onShareClick: () -> Unit,
onDownloadClick: () -> Unit,
onInfoClick: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Column( Column(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 20.dp, start = 16.dp, end = 16.dp), .padding(horizontal = 16.dp),
) { ) {
Spacer(modifier = Modifier.height(20.dp))
FilenameRow( FilenameRow(
audio = audio, audio = audio,
onClick = onClick, onClick = onClick,
) )
val caption = audio.mediaInfo.caption val caption = audio.mediaInfo.caption
if (caption != null) { if (caption != null) {
Spacer(modifier = Modifier.height(16.dp)) CaptionView(caption)
Caption(caption) } else {
Spacer(modifier = Modifier.height(20.dp))
} }
Spacer(modifier = Modifier.height(16.dp))
ActionIconsRow(
onShareClick = onShareClick,
onDownloadClick = onDownloadClick,
onInfoClick = onInfoClick,
)
HorizontalDivider() HorizontalDivider()
} }
} }
@ -101,16 +91,6 @@ private fun FilenameRow(
imageVector = Icons.Outlined.GraphicEq, imageVector = Icons.Outlined.GraphicEq,
contentDescription = null, 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)) Spacer(modifier = Modifier.width(8.dp))
Text( Text(
text = audio.mediaInfo.filename, 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 @PreviewsDayNight
@Composable @Composable
internal fun AudioItemViewPreview( internal fun AudioItemViewPreview(
@ -188,8 +119,5 @@ internal fun AudioItemViewPreview(
AudioItemView( AudioItemView(
audio = audio, audio = audio,
onClick = {}, onClick = {},
onShareClick = {},
onDownloadClick = {},
onInfoClick = {},
) )
} }

View file

@ -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,
)
}

View file

@ -9,7 +9,6 @@ package io.element.android.libraries.mediaviewer.impl.gallery.ui
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer 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.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.HorizontalDivider 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.Icon
import io.element.android.libraries.designsystem.theme.components.IconButton
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.mediaviewer.impl.gallery.MediaItem import io.element.android.libraries.mediaviewer.impl.gallery.MediaItem
@ -42,31 +40,24 @@ import io.element.android.libraries.mediaviewer.impl.gallery.MediaItem
fun FileItemView( fun FileItemView(
file: MediaItem.File, file: MediaItem.File,
onClick: () -> Unit, onClick: () -> Unit,
onShareClick: () -> Unit,
onDownloadClick: () -> Unit,
onInfoClick: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Column( Column(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 20.dp, start = 16.dp, end = 16.dp), .padding(horizontal = 16.dp),
) { ) {
Spacer(modifier = Modifier.height(20.dp))
FilenameRow( FilenameRow(
file = file, file = file,
onClick = onClick, onClick = onClick,
) )
val caption = file.mediaInfo.caption val caption = file.mediaInfo.caption
if (caption != null) { if (caption != null) {
Spacer(modifier = Modifier.height(16.dp)) CaptionView(caption)
Caption(caption) } else {
Spacer(modifier = Modifier.height(20.dp))
} }
Spacer(modifier = Modifier.height(16.dp))
ActionIconsRow(
onShareClick = onShareClick,
onDownloadClick = onDownloadClick,
onInfoClick = onInfoClick,
)
HorizontalDivider() 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 @PreviewsDayNight
@Composable @Composable
internal fun FileItemViewPreview( internal fun FileItemViewPreview(
@ -176,8 +118,5 @@ internal fun FileItemViewPreview(
FileItemView( FileItemView(
file = file, file = file,
onClick = {}, onClick = {},
onShareClick = {},
onDownloadClick = {},
onInfoClick = {},
) )
} }

View file

@ -32,7 +32,6 @@ fun aMediaItemAudio(
id: UniqueId = UniqueId("fileId"), id: UniqueId = UniqueId("fileId"),
filename: String = "filename", filename: String = "filename",
caption: String? = null, caption: String? = null,
duration: String? = "1:23",
): MediaItem.Audio { ): MediaItem.Audio {
return MediaItem.Audio( return MediaItem.Audio(
id = id, id = id,
@ -42,6 +41,5 @@ fun aMediaItemAudio(
caption = caption, caption = caption,
), ),
mediaSource = MediaSource(""), mediaSource = MediaSource(""),
duration = duration,
) )
} }

View file

@ -66,18 +66,19 @@ fun VoiceItemView(
Column( Column(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 20.dp, start = 16.dp, end = 16.dp), .padding(horizontal = 16.dp),
) { ) {
Spacer(modifier = Modifier.height(20.dp))
VoiceInfoRow( VoiceInfoRow(
state = state, state = state,
voice = voice, voice = voice,
) )
val caption = voice.mediaInfo.caption val caption = voice.mediaInfo.caption
if (caption != null) { if (caption != null) {
CaptionView(caption)
} else {
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
Caption(caption)
} }
Spacer(modifier = Modifier.height(16.dp))
ActionIconsRow( ActionIconsRow(
onShareClick = onShareClick, onShareClick = onShareClick,
onDownloadClick = onDownloadClick, onDownloadClick = onDownloadClick,
@ -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 @Composable
private fun ActionIconsRow( private fun ActionIconsRow(
onShareClick: () -> Unit, onShareClick: () -> Unit,

View file

@ -262,7 +262,6 @@ class DefaultEventItemFactoryTest {
waveform = null, waveform = null,
), ),
mediaSource = MediaSource(""), mediaSource = MediaSource(""),
duration = "7:36",
) )
) )
} }