Merge pull request #6322 from element-hq/feature/bma/iterateDesignOnAttachment

Design iteration on file attachment in the timeline
This commit is contained in:
Benoit Marty 2026-03-23 14:37:54 +01:00 committed by GitHub
commit 93ab9f43dc
35 changed files with 112 additions and 81 deletions

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files 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.BoxScope
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.theme.messageFromMeBackground
@Composable
internal fun ElementTimelineItemPreview(
content: @Composable BoxScope.() -> Unit,
) = ElementPreview {
Box(
modifier = Modifier
.background(ElementTheme.colors.messageFromMeBackground)
.padding(4.dp),
content = content,
)
}

View file

@ -9,18 +9,16 @@
package io.element.android.features.messages.impl.timeline.components.event package io.element.android.features.messages.impl.timeline.components.event
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
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.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
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
@ -73,17 +71,17 @@ private fun TimelineItemAttachmentHeaderView(
val spacing = 8.dp val spacing = 8.dp
Row( Row(
modifier = modifier, modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(spacing),
) { ) {
Box( Box(
modifier = Modifier modifier = Modifier
.size(iconSize) .size(iconSize)
.clip(CircleShape) .background(ElementTheme.colors.bgCanvasDefault, RoundedCornerShape(4.dp)),
.background(ElementTheme.colors.bgCanvasDefault),
contentAlignment = Alignment.Center, contentAlignment = Alignment.Center,
) { ) {
icon() icon()
} }
Spacer(Modifier.width(spacing))
Column { Column {
Text( Text(
text = filename, text = filename,

View file

@ -18,7 +18,6 @@ import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayoutData 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.TimelineItemAudioContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContentProvider 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.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Icon
@ -49,7 +48,7 @@ fun TimelineItemAudioView(
@PreviewsDayNight @PreviewsDayNight
@Composable @Composable
internal fun TimelineItemAudioViewPreview(@PreviewParameter(TimelineItemAudioContentProvider::class) content: TimelineItemAudioContent) = internal fun TimelineItemAudioViewPreview(@PreviewParameter(TimelineItemAudioContentProvider::class) content: TimelineItemAudioContent) =
ElementPreview { ElementTimelineItemPreview {
TimelineItemAudioView( TimelineItemAudioView(
content, content,
onContentLayoutChange = {}, onContentLayoutChange = {},

View file

@ -11,20 +11,21 @@ package io.element.android.features.messages.impl.timeline.components.event
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
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.features.messages.impl.timeline.components.layout.ContentAvoidingLayoutData 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.TimelineItemFileContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContentProvider import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContentProvider
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.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
/**
* https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=2019-6477&t=2yr7kvVEdtsP4p26-4
*/
@Composable @Composable
fun TimelineItemFileView( fun TimelineItemFileView(
content: TimelineItemFileContent, content: TimelineItemFileContent,
@ -39,12 +40,11 @@ fun TimelineItemFileView(
modifier = modifier, modifier = modifier,
icon = { icon = {
Icon( Icon(
resourceId = CompoundDrawables.ic_compound_attachment, imageVector = CompoundIcons.Attachment(),
contentDescription = stringResource(CommonStrings.common_file), contentDescription = stringResource(CommonStrings.common_file),
tint = ElementTheme.colors.iconPrimary, tint = ElementTheme.colors.iconPrimary,
modifier = Modifier modifier = Modifier
.size(16.dp) .size(16.dp),
.rotate(-45f),
) )
} }
) )
@ -52,9 +52,11 @@ fun TimelineItemFileView(
@PreviewsDayNight @PreviewsDayNight
@Composable @Composable
internal fun TimelineItemFileViewPreview(@PreviewParameter(TimelineItemFileContentProvider::class) content: TimelineItemFileContent) = ElementPreview { internal fun TimelineItemFileViewPreview(@PreviewParameter(TimelineItemFileContentProvider::class) content: TimelineItemFileContent) {
TimelineItemFileView( ElementTimelineItemPreview {
content, TimelineItemFileView(
onContentLayoutChange = {}, content,
) onContentLayoutChange = {},
)
}
} }

View file

@ -61,7 +61,8 @@ class KonsistPreviewTest {
.functions() .functions()
.withAllAnnotationsOf(PreviewsDayNight::class) .withAllAnnotationsOf(PreviewsDayNight::class)
.assertTrue { .assertTrue {
it.text.contains("ElementPreview") it.text.contains("ElementPreview") ||
it.text.contains("ElementTimelineItemPreview")
} }
} }

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:c14bc53d1e715f41d26fdc37a9fe8f993d96d7d6378d1684240c1d7935de982c oid sha256:cd7dd5cac80d616404984e3c9ac4916bcead2f0f5889bb4b6fe7c9be45b74288
size 43438 size 42276

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:f59ac263a6b72c4f7fcffe190deaf3eb15697b9dec81f51dae850bfd19c752c3 oid sha256:1b874cff34a0c93cd34b6f641d59309d255b47fc3ddc900a8d98f7d464a05886
size 42022 size 40871

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:42b0ad7414ecdd7c15e1fcf6f5dadc86eb4091b0af21af2c30e7285dc8892c7b oid sha256:24a6182c7262cf305bd74e6e15c8382440ea38280f9aa240736d69b7ca9b8262
size 8864 size 8980

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:3d09baeba55c0a3fb73459e82ca092252a9ccafb04447180a49903c26f27e346 oid sha256:d7d530182bc0e138572a5b2c09cc9e0cb12a4abd74f461161011001db2e8a68e
size 11152 size 11134

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:a459e3edff1e74c680618a206afc7b682cc108a0e911fad31fb681f5bdaf91f7 oid sha256:b61be67926786b1a4ddfc48c35b2806ae99828cc3f124cd16f0f43123c6601e1
size 21769 size 21239

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:d0e0f6914d94d9f1cbf99b50aca76b07cbf3703ea829bf4120cb2cc46d5f6a72 oid sha256:71fad05e5c0a44e26d469ad729e6081ae0a8acb687983b1ffdf3ea4b9dba0567
size 10998 size 11076

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:3d553d0cd61616154b96424c81d40746149e9451ef8fb2a83a863eacc3bd67ae oid sha256:a8c5c2e227c18d401b134874a48d9e02e83dd0a3da3c72a2d8be3e066ff4252c
size 21615 size 21319

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:48739ba311ea5d33785adb461173c5b0e523db2b7162a8560870bb4e410381b7 oid sha256:ec6848be6db0a228e9b0ab5bf3885a976123f2dd6081b756d39e0715329cc773
size 8912 size 8650

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:09638751489f794aa88ac4f42fb5433aeccec752f67848bb0fb5b46cba4ccc0a oid sha256:8bdb973cd0441a1ae6b646c5fa9cef7660ca5e084fd3273a2f7271db696abaef
size 11098 size 10713

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:59e0bb151a172f6e6b764f575936b8aacd2313fee00b0cf97bee97c87ffde1e7 oid sha256:d0f022ee3377513370860a8ec1c0898fa226139f57f54c767a91605f8a608343
size 21346 size 20377

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:3529ac3a3c31be05dc41257dfd06cb2463cfd212abcd77ad147b30caa51abd8f oid sha256:792c78cdce5a86d44e304aa831c1728e0e44d2971ce71f60ffc2f2efcd28c244
size 10959 size 10715

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:00ff513e42f14a1b3028963b4c93592b558a71658ee27af931911cdde9d5522a oid sha256:5143000ddf118a9260cf9bf149ac66aa798f6e87a5c6e8d2feadcfdd969303c1
size 21116 size 20366

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:cda074f3b92eef041be1fee3ca3d03611d7316c29844dbe5c237f0ff8c47bb81 oid sha256:bea2db8117d8616f2f1566d4056e2f3951360d550270256957608c10c16735c3
size 8103 size 8011

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:6115a17cda5ad61e95f7c0d673350d3e6e43cd4174a89e17c90e83c8884e9c61 oid sha256:6d39497a2ac31dba1061ab8294739568aecfd33ef16663be8e4d71f5c64138e0
size 10487 size 10341

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:592ce847c0fc473b4c54109aae92124241c18fb802ccbc4a928becc82489b82a oid sha256:f176b2e2ca7176763d9dbc5cd509026f3ca778988a302f764e291fc4dca2a321
size 21723 size 20899

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:73260ff6f0aa0986c3e29ec05da9732a8f5ae9b8426935371ed059b59e63f0e7 oid sha256:a0716914ef0ccced55c54a77de7e6ead452b8292eeb2fff2c696eb0ddb38168d
size 10222 size 10113

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:069f5e7d8ea9bf820c0540010aee54b262c08284e81936473b757b5769a52740 oid sha256:2bb8167bb74b99425ea606ce4cfd96a69d8e0cf2626f3c8a2ee9c1a0ac123b78
size 20963 size 20409

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:2620bc4c9a895153e22dfb5f06bcf9cb6a69ea0c3027f7ceb885e856a66841c0 oid sha256:fefa92eb1a8507bbb060bb4ed8d6d541dd234eb166a19fb022de1fc90a0909ec
size 8184 size 7819

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:bfac39444160e5bf8a14c65d6d1419596530de36ebbfa54d706fe6f4e2dbb5ca oid sha256:6038a32065dd17a0bb1c442beaebabb0c35c4e035f325fd8264523653e9591d4
size 10385 size 10000

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:739de371fc4c64baf153ed17aef54a3b7cdd8c4b3e63a6bf630b802242d6076a oid sha256:2f2a066ef268c6f07301eb20e4129c36a4cc811faeda8633e2e10e8e670fdfbc
size 21139 size 20067

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:b169fd31d4cc125aac493cf42126d90d09fe04991489f5f5422ca17a9727b661 oid sha256:5f46cd619af4e771e9ee5f99336f99b98a8b641799a667ee162f59b17d1900fa
size 10227 size 9882

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:6526af014d855dafbe05f54da0b8e55bb574346c9439e5f76f82f315b932ba45 oid sha256:cce655b1c1731e92c035dcadd5cfd4e482858dfb3a033c871c6d57def5210341
size 20436 size 19585

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:957312e43fe52a1a249313e0e9b41014230a0127bc02807582bbb8127af10aab oid sha256:3acf49b0e6de15ca8c39e3eba0ef8560dd1c69928b98dcda7b03845dc22b60f6
size 70057 size 65762

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:500160908ba6f2dd7eb56a45ff912a793c0369691c2cc4cb166e2a9adbd4366c oid sha256:93d04877db6a4f7165edd4a77289af416a5d41df23f256d5b7b112a74aed220d
size 84418 size 81046

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:0f6e8c0c53aac7163d900690abca8e5f9198ed25ae123c71f144717d1d04740b oid sha256:089982f83fdf0b0a05abd0cd13c8f32bcd8162363ec3e898ab72536d731e70d6
size 72936 size 70626

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:5de8dc9041aa3e727c0d493facbae65a83b353093542c6c11af57ad8f7508ccf oid sha256:7225dd8d4e7a9097732896f97f88526e0538dcc9b446d77dd7a08209c9fc440e
size 102505 size 100673

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:8b7045644b2a74859b613ab68476ba08a36d6461cfec0ebc939364db03b8f970 oid sha256:6df365a6f724a26528a1205d95088a17cd16f2ac5541259264b149083f68a975
size 68934 size 64837

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:c1a6d35319e6143276f9bf399aa095374bae12972d3256ec966ce70de65df3c4 oid sha256:50995b749db8be8b9873930dd0e1b3f15bdba2d8ce54d02a4b5dfaf4bf643301
size 82636 size 79499

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:551ddf5dce180f019cdc13296f5e67383a69c67ea55496b5a8ec8cfbdea7dee3 oid sha256:f4baf2815c774a4e93adf85d57ff0d20d5039d260ac164c8b5092019e2a2fd5f
size 72048 size 69497

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:2c555798e54de958bf6d982cb70a69014b93fb3862b1744783e85c81611a167c oid sha256:cb3775d7291705e74af8647ba3cf18c2c0353f90f33b98cc93e46a48a3e4f78c
size 100384 size 98346