From f353ecdd45154296ad1c28eada8afaf554ec5fb0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 Nov 2024 10:00:43 +0100 Subject: [PATCH] Render caption below audio and file Event in the timeline. --- .../event/TimelineItemAttachmentView.kt | 128 ++++++++++++++++++ .../components/event/TimelineItemAudioView.kt | 52 +------ .../components/event/TimelineItemFileView.kt | 52 +------ .../event/TimelineItemAudioContentProvider.kt | 11 +- .../event/TimelineItemFileContentProvider.kt | 7 +- 5 files changed, 155 insertions(+), 95 deletions(-) create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAttachmentView.kt diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAttachmentView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAttachmentView.kt new file mode 100644 index 0000000000..2624a8b5e7 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAttachmentView.kt @@ -0,0 +1,128 @@ +/* + * 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.features.messages.impl.timeline.components.event + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayout +import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayoutData +import io.element.android.libraries.designsystem.theme.components.Text + +/** + * package-private, you should only use TimelineItemFileView and TimelineItemAudioView. + */ +@Composable +fun TimelineItemAttachmentView( + filename: String, + fileExtensionAndSize: String, + caption: String?, + onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, + modifier: Modifier = Modifier, + icon: (@Composable () -> Unit) = {}, +) { + Column( + modifier = modifier, + ) { + TimelineItemAttachmentHeaderView( + filename = filename, + fileExtensionAndSize = fileExtensionAndSize, + hasCaption = caption != null, + onContentLayoutChange = onContentLayoutChange, + icon = icon, + ) + if (caption != null) { + TimelineItemAttachmentCaptionView( + modifier = Modifier.padding(top = 4.dp), + caption = caption, + onContentLayoutChange = onContentLayoutChange, + ) + } + } +} + +@Composable +private fun TimelineItemAttachmentHeaderView( + filename: String, + fileExtensionAndSize: String, + hasCaption: Boolean, + onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, + modifier: Modifier = Modifier, + icon: (@Composable () -> Unit), +) { + val iconSize = 32.dp + val spacing = 8.dp + Row( + modifier = modifier, + ) { + Box( + modifier = Modifier + .size(iconSize) + .clip(CircleShape) + .background(ElementTheme.materialColors.background), + contentAlignment = Alignment.Center, + ) { + icon() + } + Spacer(Modifier.width(spacing)) + Column { + Text( + text = filename, + color = ElementTheme.materialColors.primary, + maxLines = 2, + style = ElementTheme.typography.fontBodyLgRegular, + overflow = TextOverflow.Ellipsis + ) + Text( + text = fileExtensionAndSize, + color = ElementTheme.materialColors.secondary, + style = ElementTheme.typography.fontBodySmRegular, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + onTextLayout = if (hasCaption) { + {} + } else { + ContentAvoidingLayout.measureLastTextLine( + onContentLayoutChange = onContentLayoutChange, + extraWidth = iconSize + spacing + ) + }, + ) + } + } +} + +@Composable +private fun TimelineItemAttachmentCaptionView( + caption: String, + onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, + modifier: Modifier = Modifier, +) { + Text( + modifier = modifier, + text = caption, + color = ElementTheme.materialColors.primary, + style = ElementTheme.typography.fontBodyLgRegular, + onTextLayout = ContentAvoidingLayout.measureLastTextLine( + onContentLayoutChange = onContentLayoutChange, + ) + ) +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAudioView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAudioView.kt index 23069a1fac..32e97eed58 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAudioView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAudioView.kt @@ -7,32 +7,20 @@ package io.element.android.features.messages.impl.timeline.components.event -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.GraphicEq import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -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.features.messages.impl.timeline.components.layout.ContentAvoidingLayout import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayoutData import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContentProvider import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.theme.components.Text @Composable fun TimelineItemAudioView( @@ -40,18 +28,13 @@ fun TimelineItemAudioView( onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, modifier: Modifier = Modifier, ) { - val iconSize = 32.dp - val spacing = 8.dp - Row( + TimelineItemAttachmentView( + filename = content.filename, + fileExtensionAndSize = content.fileExtensionAndSize, + caption = content.caption, + onContentLayoutChange = onContentLayoutChange, modifier = modifier, - ) { - Box( - modifier = Modifier - .size(iconSize) - .clip(CircleShape) - .background(ElementTheme.materialColors.background), - contentAlignment = Alignment.Center, - ) { + icon = { Icon( imageVector = Icons.Outlined.GraphicEq, contentDescription = null, @@ -60,28 +43,7 @@ fun TimelineItemAudioView( .size(16.dp), ) } - Spacer(Modifier.width(spacing)) - Column { - Text( - text = content.bestDescription, - color = ElementTheme.materialColors.primary, - maxLines = 2, - style = ElementTheme.typography.fontBodyLgRegular, - overflow = TextOverflow.Ellipsis - ) - Text( - text = content.fileExtensionAndSize, - color = ElementTheme.materialColors.secondary, - style = ElementTheme.typography.fontBodySmRegular, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - onTextLayout = ContentAvoidingLayout.measureLastTextLine( - onContentLayoutChange = onContentLayoutChange, - extraWidth = iconSize + spacing - ) - ) - } - } + ) } @PreviewsDayNight diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemFileView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemFileView.kt index dadfadc299..a3cdd7701e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemFileView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemFileView.kt @@ -7,24 +7,13 @@ package io.element.android.features.messages.impl.timeline.components.event -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.rotate -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.features.messages.impl.timeline.components.layout.ContentAvoidingLayout import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayoutData import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContentProvider @@ -32,7 +21,6 @@ import io.element.android.libraries.designsystem.icons.CompoundDrawables import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.theme.components.Text @Composable fun TimelineItemFileView( @@ -40,18 +28,13 @@ fun TimelineItemFileView( onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, modifier: Modifier = Modifier, ) { - val iconSize = 32.dp - val spacing = 8.dp - Row( + TimelineItemAttachmentView( + filename = content.filename, + fileExtensionAndSize = content.fileExtensionAndSize, + caption = content.caption, + onContentLayoutChange = onContentLayoutChange, modifier = modifier, - ) { - Box( - modifier = Modifier - .size(iconSize) - .clip(CircleShape) - .background(ElementTheme.materialColors.background), - contentAlignment = Alignment.Center, - ) { + icon = { Icon( resourceId = CompoundDrawables.ic_compound_attachment, contentDescription = null, @@ -61,28 +44,7 @@ fun TimelineItemFileView( .rotate(-45f), ) } - Spacer(Modifier.width(spacing)) - Column { - Text( - text = content.bestDescription, - color = ElementTheme.materialColors.primary, - maxLines = 2, - style = ElementTheme.typography.fontBodyLgRegular, - overflow = TextOverflow.Ellipsis - ) - Text( - text = content.fileExtensionAndSize, - color = ElementTheme.materialColors.secondary, - style = ElementTheme.typography.fontBodySmRegular, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - onTextLayout = ContentAvoidingLayout.measureLastTextLine( - onContentLayoutChange = onContentLayoutChange, - extraWidth = iconSize + spacing - ) - ) - } - } + ) } @PreviewsDayNight diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt index 41dab0cfb6..d3ca18e836 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt @@ -17,13 +17,18 @@ open class TimelineItemAudioContentProvider : PreviewParameterProvider