Thread decoration: create the ThreadDecoration ui
This commit is contained in:
parent
04c82aa1a5
commit
9f5666ac0c
2 changed files with 87 additions and 36 deletions
|
|
@ -75,6 +75,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
|||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemPollContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent
|
||||
import io.element.android.libraries.designsystem.R
|
||||
import io.element.android.libraries.designsystem.colors.AvatarColorsProvider
|
||||
import io.element.android.libraries.designsystem.components.EqualWidthColumn
|
||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||
|
|
@ -84,6 +85,7 @@ import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
|||
import io.element.android.libraries.designsystem.swipe.SwipeableActionsState
|
||||
import io.element.android.libraries.designsystem.swipe.rememberSwipeableActionsState
|
||||
import io.element.android.libraries.designsystem.text.toPx
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
|
|
@ -370,14 +372,6 @@ private fun MessageEventBubbleContent(
|
|||
onPollAnswerSelected: (pollStartId: EventId, answerId: String) -> Unit,
|
||||
@SuppressLint("ModifierParameter") bubbleModifier: Modifier = Modifier, // need to rename this modifier to distinguish it from the following ones
|
||||
) {
|
||||
val timestampPosition = when (event.content) {
|
||||
is TimelineItemImageContent,
|
||||
is TimelineItemVideoContent,
|
||||
is TimelineItemLocationContent -> TimestampPosition.Overlay
|
||||
is TimelineItemPollContent -> TimestampPosition.Below
|
||||
else -> TimestampPosition.Default
|
||||
}
|
||||
val replyToDetails = event.inReplyTo as? InReplyTo.Ready
|
||||
|
||||
// Long clicks are not not automatically propagated from a `clickable`
|
||||
// to its `combinedClickable` parent so we do it manually
|
||||
|
|
@ -398,6 +392,21 @@ private fun MessageEventBubbleContent(
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ThreadDecoration(
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Row(modifier, verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(resourceId = R.drawable.ic_thread_decoration, contentDescription = null, tint = ElementTheme.colors.iconSecondary)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text(
|
||||
text = "Thread",
|
||||
style = ElementTheme.typography.fontBodyXsRegular,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ContentAndTimestampView(
|
||||
timestampPosition: TimestampPosition,
|
||||
|
|
@ -450,47 +459,74 @@ private fun MessageEventBubbleContent(
|
|||
/** Groups the different components in a Column with some space between them. */
|
||||
@Composable
|
||||
fun CommonLayout(
|
||||
timestampPosition: TimestampPosition,
|
||||
showThreadDecoration: Boolean,
|
||||
inReplyToDetails: InReplyTo.Ready?,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
var modifierWithPadding: Modifier = Modifier
|
||||
var contentModifier: Modifier = Modifier
|
||||
EqualWidthColumn(modifier = modifier, spacing = 8.dp) {
|
||||
when {
|
||||
inReplyToDetails != null -> {
|
||||
val senderName = inReplyToDetails.senderDisplayName ?: inReplyToDetails.senderId.value
|
||||
val attachmentThumbnailInfo = attachmentThumbnailInfoForInReplyTo(inReplyToDetails)
|
||||
val text = textForInReplyTo(inReplyToDetails)
|
||||
ReplyToContent(
|
||||
senderName = senderName,
|
||||
text = text,
|
||||
attachmentThumbnailInfo = attachmentThumbnailInfo,
|
||||
modifier = Modifier
|
||||
.padding(top = 8.dp, start = 8.dp, end = 8.dp)
|
||||
.clip(RoundedCornerShape(6.dp))
|
||||
.clickable(enabled = true, onClick = inReplyToClick),
|
||||
)
|
||||
if (timestampPosition == TimestampPosition.Overlay) {
|
||||
modifierWithPadding = Modifier.padding(start = 8.dp, end = 8.dp, bottom = 8.dp)
|
||||
contentModifier = Modifier.clip(RoundedCornerShape(12.dp))
|
||||
} else {
|
||||
contentModifier = Modifier.padding(start = 12.dp, end = 12.dp, top = 0.dp, bottom = 8.dp)
|
||||
}
|
||||
}
|
||||
timestampPosition != TimestampPosition.Overlay -> {
|
||||
contentModifier = Modifier.padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 8.dp)
|
||||
val modifierWithPadding: Modifier
|
||||
val contentModifier: Modifier
|
||||
when {
|
||||
inReplyToDetails != null -> {
|
||||
if (timestampPosition == TimestampPosition.Overlay) {
|
||||
modifierWithPadding = Modifier.padding(start = 8.dp, end = 8.dp, bottom = 8.dp)
|
||||
contentModifier = Modifier.clip(RoundedCornerShape(12.dp))
|
||||
} else {
|
||||
contentModifier = Modifier.padding(start = 12.dp, end = 12.dp, top = 0.dp, bottom = 8.dp)
|
||||
modifierWithPadding = Modifier
|
||||
}
|
||||
}
|
||||
timestampPosition != TimestampPosition.Overlay -> {
|
||||
modifierWithPadding = Modifier
|
||||
contentModifier = Modifier.padding(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 8.dp)
|
||||
}
|
||||
else -> {
|
||||
modifierWithPadding = Modifier
|
||||
contentModifier = Modifier
|
||||
}
|
||||
}
|
||||
|
||||
EqualWidthColumn(modifier = modifier, spacing = 8.dp) {
|
||||
if (showThreadDecoration) {
|
||||
ThreadDecoration(modifier = Modifier.padding(top = 8.dp, start = 12.dp, end = 12.dp))
|
||||
}
|
||||
if (inReplyToDetails != null) {
|
||||
val senderName = inReplyToDetails.senderDisplayName ?: inReplyToDetails.senderId.value
|
||||
val attachmentThumbnailInfo = attachmentThumbnailInfoForInReplyTo(inReplyToDetails)
|
||||
val text = textForInReplyTo(inReplyToDetails)
|
||||
val topPadding = if (showThreadDecoration) 0.dp else 8.dp
|
||||
ReplyToContent(
|
||||
senderName = senderName,
|
||||
text = text,
|
||||
attachmentThumbnailInfo = attachmentThumbnailInfo,
|
||||
modifier = Modifier
|
||||
.padding(top = topPadding, start = 8.dp, end = 8.dp)
|
||||
.clip(RoundedCornerShape(6.dp))
|
||||
.clickable(enabled = true, onClick = inReplyToClick),
|
||||
)
|
||||
}
|
||||
ContentAndTimestampView(
|
||||
timestampPosition = timestampPosition,
|
||||
contentModifier = contentModifier,
|
||||
modifier = modifierWithPadding,
|
||||
contentModifier = contentModifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
CommonLayout(inReplyToDetails = replyToDetails, modifier = bubbleModifier)
|
||||
val timestampPosition = when (event.content) {
|
||||
is TimelineItemImageContent,
|
||||
is TimelineItemVideoContent,
|
||||
is TimelineItemLocationContent -> TimestampPosition.Overlay
|
||||
is TimelineItemPollContent -> TimestampPosition.Below
|
||||
else -> TimestampPosition.Default
|
||||
}
|
||||
val replyToDetails = event.inReplyTo as? InReplyTo.Ready
|
||||
CommonLayout(
|
||||
showThreadDecoration = false,
|
||||
timestampPosition = timestampPosition,
|
||||
inReplyToDetails = replyToDetails,
|
||||
modifier = bubbleModifier
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="14dp"
|
||||
android:height="13dp"
|
||||
android:viewportWidth="14"
|
||||
android:viewportHeight="13">
|
||||
<path
|
||||
android:pathData="M3.667,4.667C3.478,4.667 3.319,4.603 3.192,4.475C3.064,4.347 3,4.189 3,4C3,3.811 3.064,3.653 3.192,3.525C3.319,3.397 3.478,3.333 3.667,3.333H10.333C10.522,3.333 10.681,3.397 10.808,3.525C10.936,3.653 11,3.811 11,4C11,4.189 10.936,4.347 10.808,4.475C10.681,4.603 10.522,4.667 10.333,4.667H3.667Z"
|
||||
android:fillColor="#656D77"/>
|
||||
<path
|
||||
android:pathData="M3.667,7.333C3.478,7.333 3.319,7.269 3.192,7.142C3.064,7.014 3,6.856 3,6.667C3,6.478 3.064,6.319 3.192,6.192C3.319,6.064 3.478,6 3.667,6H7.667C7.855,6 8.014,6.064 8.142,6.192C8.269,6.319 8.333,6.478 8.333,6.667C8.333,6.856 8.269,7.014 8.142,7.142C8.014,7.269 7.855,7.333 7.667,7.333H3.667Z"
|
||||
android:fillColor="#656D77"/>
|
||||
<path
|
||||
android:pathData="M1.471,12.195C1.051,12.615 0.333,12.318 0.333,11.724V1.333C0.333,0.597 0.93,0 1.667,0H12.333C13.07,0 13.667,0.597 13.667,1.333V9.333C13.667,10.07 13.07,10.667 12.333,10.667H3L1.471,12.195ZM3,9.333H12.333V1.333H1.667V10.114L2.057,9.724C2.307,9.474 2.646,9.333 3,9.333Z"
|
||||
android:fillColor="#656D77"/>
|
||||
</vector>
|
||||
Loading…
Add table
Add a link
Reference in a new issue