Design: iterate on Room List item
This commit is contained in:
parent
23adc32cd2
commit
7d69e9a4dd
2 changed files with 102 additions and 88 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue