Design: iterate on Room List item

This commit is contained in:
Benoit Marty 2023-06-21 17:31:05 +02:00 committed by Benoit Marty
parent 23adc32cd2
commit 7d69e9a4dd
2 changed files with 102 additions and 88 deletions

View file

@ -24,8 +24,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.heightIn
@ -37,7 +36,6 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Rect import androidx.compose.ui.geometry.Rect
@ -70,7 +68,7 @@ import io.element.android.libraries.designsystem.theme.roomListRoomMessageDate
import io.element.android.libraries.designsystem.theme.roomListRoomName import io.element.android.libraries.designsystem.theme.roomListRoomName
import io.element.android.libraries.designsystem.theme.roomListUnreadIndicator import io.element.android.libraries.designsystem.theme.roomListUnreadIndicator
private val minHeight = 72.dp private val minHeight = 84.dp
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
@ -81,108 +79,116 @@ internal fun RoomSummaryRow(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val clickModifier = if (room.isPlaceholder) { val clickModifier = if (room.isPlaceholder) {
modifier Modifier
} else { } else {
modifier.combinedClickable( Modifier.combinedClickable(
onClick = { onClick(room) }, onClick = { onClick(room) },
onLongClick = { onLongClick(room) }, onLongClick = { onLongClick(room) },
indication = rememberRipple(), indication = rememberRipple(),
interactionSource = remember { MutableInteractionSource() } interactionSource = remember { MutableInteractionSource() }
) )
} }
Box(
Row(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.heightIn(min = minHeight) .heightIn(min = minHeight)
.then(clickModifier) .then(clickModifier)
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 11.dp)
.height(IntrinsicSize.Min),
) { ) {
DefaultRoomSummaryRow(room = room) Avatar(
room
.avatarData,
modifier = Modifier
.align(Alignment.CenterVertically)
.placeholder(
visible = room.isPlaceholder,
shape = CircleShape,
color = ElementTheme.colors.roomListPlaceHolder(),
)
)
Column(
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp)
) {
Row(modifier = Modifier.fillMaxWidth()) {
NameAndTimestampRow(room = room)
}
Row(modifier = Modifier.fillMaxWidth()) {
LastMessageAndIndicatorRow(room = room)
}
}
} }
} }
@Composable @Composable
internal fun DefaultRoomSummaryRow( private fun RowScope.NameAndTimestampRow(room: RoomListRoomSummary) {
room: RoomListRoomSummary, // Name
) { Text(
Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .weight(1f)
.padding(horizontal = 16.dp) .padding(end = 16.dp)
.defaultMinSize(minHeight = 84.dp) .placeholder(
.height(IntrinsicSize.Min),
verticalAlignment = CenterVertically
) {
Avatar(
room.avatarData,
modifier = Modifier.placeholder(
visible = room.isPlaceholder, visible = room.isPlaceholder,
shape = CircleShape, shape = TextPlaceholderShape,
color = ElementTheme.colors.roomListPlaceHolder(), color = ElementTheme.colors.roomListPlaceHolder(),
) ),
) fontSize = 16.sp,
Column( fontWeight = FontWeight.SemiBold,
modifier = Modifier style = MaterialTheme.typography.bodyMedium,
.padding(start = 12.dp, end = 4.dp, top = 12.dp, bottom = 12.dp) text = room.name,
.alignByBaseline() color = MaterialTheme.roomListRoomName(),
.weight(1f) maxLines = 1,
) { overflow = TextOverflow.Ellipsis
// Name )
Text( // Timestamp
modifier = Modifier.placeholder( Text(
visible = room.isPlaceholder, modifier = Modifier
shape = TextPlaceholderShape, .placeholder(
color = ElementTheme.colors.roomListPlaceHolder(), visible = room.isPlaceholder,
), shape = TextPlaceholderShape,
fontSize = 16.sp, color = ElementTheme.colors.roomListPlaceHolder(),
fontWeight = FontWeight.SemiBold, ),
text = room.name, fontSize = 12.sp,
color = MaterialTheme.roomListRoomName(), text = room.timestamp ?: "",
maxLines = 1, color = MaterialTheme.roomListRoomMessageDate(),
overflow = TextOverflow.Ellipsis )
) }
// Last Message
val attributedLastMessage = (room.lastMessage as? AnnotatedString) @Composable
?: AnnotatedString(room.lastMessage.orEmpty().toString()) private fun RowScope.LastMessageAndIndicatorRow(room: RoomListRoomSummary) {
Text( // Last Message
modifier = Modifier.placeholder( val attributedLastMessage = (room.lastMessage as? AnnotatedString)
visible = room.isPlaceholder, ?: AnnotatedString(room.lastMessage.orEmpty().toString())
shape = TextPlaceholderShape, Text(
color = ElementTheme.colors.roomListPlaceHolder(), modifier = Modifier
), .weight(1f)
text = attributedLastMessage, .padding(end = 28.dp)
color = MaterialTheme.roomListRoomMessage(), .placeholder(
fontSize = 14.sp, visible = room.isPlaceholder,
maxLines = 1, shape = TextPlaceholderShape,
overflow = TextOverflow.Ellipsis color = ElementTheme.colors.roomListPlaceHolder(),
) ),
} text = attributedLastMessage,
// Timestamp and Unread color = MaterialTheme.roomListRoomMessage(),
Column( fontSize = 14.sp,
modifier = Modifier style = MaterialTheme.typography.bodySmall,
.alignByBaseline(), maxLines = 2,
) { overflow = TextOverflow.Ellipsis
Text( )
modifier = Modifier.placeholder( // Unread
visible = room.isPlaceholder, val unreadIndicatorColor =
shape = TextPlaceholderShape, if (room.hasUnread) MaterialTheme.roomListUnreadIndicator() else Color.Transparent
color = ElementTheme.colors.roomListPlaceHolder(), Box(
), modifier = Modifier
fontSize = 12.sp, .padding(top = 3.dp)
text = room.timestamp ?: "", .size(12.dp)
color = MaterialTheme.roomListRoomMessageDate(), .clip(CircleShape)
) .background(unreadIndicatorColor),
Spacer(Modifier.size(4.dp)) )
val unreadIndicatorColor =
if (room.hasUnread) MaterialTheme.roomListUnreadIndicator() else Color.Transparent
Box(
modifier = Modifier
.size(12.dp)
.clip(CircleShape)
.background(unreadIndicatorColor)
.align(Alignment.End),
)
}
}
} }
val TextPlaceholderShape = PercentRectangleSizeShape(0.5f) val TextPlaceholderShape = PercentRectangleSizeShape(0.5f)

View file

@ -29,7 +29,15 @@ open class RoomListRoomSummaryProvider : PreviewParameterProvider<RoomListRoomSu
aRoomListRoomSummary().copy(hasUnread = true), aRoomListRoomSummary().copy(hasUnread = true),
aRoomListRoomSummary().copy(timestamp = "88:88"), aRoomListRoomSummary().copy(timestamp = "88:88"),
aRoomListRoomSummary().copy(timestamp = "88:88", hasUnread = true), aRoomListRoomSummary().copy(timestamp = "88:88", hasUnread = true),
aRoomListRoomSummary().copy(isPlaceholder = true), aRoomListRoomSummary().copy(isPlaceholder = true, timestamp = "88:88"),
aRoomListRoomSummary().copy(
name = "A very long room name that should be truncated",
lastMessage = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" +
" ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea com" +
"modo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
timestamp = "yesterday",
hasUnread = true,
),
) )
} }