Iterate on Room placeholder

This commit is contained in:
Benoit Marty 2023-06-23 10:38:36 +02:00 committed by Benoit Marty
parent 2bc52216f5
commit 980d5462f3
5 changed files with 191 additions and 41 deletions

View file

@ -82,6 +82,7 @@ internal fun aRoomListRoomSummaryList(): ImmutableList<RoomListRoomSummary> {
id = "!roomId2:domain",
roomId = RoomId("!roomId2:domain")
),
RoomListRoomSummaryPlaceholders.create("!roomId2:domain")
RoomListRoomSummaryPlaceholders.create("!roomId2:domain"),
RoomListRoomSummaryPlaceholders.create("!roomId3:domain"),
)
}

View file

@ -0,0 +1,104 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.features.roomlist.impl.components
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.fillMaxWidth
import androidx.compose.foundation.layout.height
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.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.atomic.atoms.PlaceholderAtom
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.ElementTheme
import io.element.android.libraries.designsystem.theme.roomListPlaceHolder
/**
* https://www.figma.com/file/0MMNu7cTOzLOlWb7ctTkv3/Element-X?node-id=6547%3A147623
*/
@Composable
internal fun RoomSummaryPlaceholderRow(
modifier: Modifier = Modifier,
) {
Row(
modifier = modifier
.fillMaxWidth()
.height(minHeight)
.padding(horizontal = 16.dp),
) {
Box(
modifier = Modifier
.size(AvatarSize.RoomListItem.dp)
.align(Alignment.CenterVertically)
.background(color = ElementTheme.colors.roomListPlaceHolder(), shape = CircleShape)
)
Column(
modifier = Modifier
.fillMaxWidth()
.padding(start = 20.dp, top = 19.dp, end = 4.dp)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(22.dp),
verticalAlignment = Alignment.CenterVertically
) {
PlaceholderAtom(width = 40.dp, height = 7.dp)
Spacer(modifier = Modifier.width(7.dp))
PlaceholderAtom(width = 45.dp, height = 7.dp)
Spacer(modifier = Modifier.weight(1f))
PlaceholderAtom(width = 22.dp, height = 4.dp)
}
Row(
modifier = Modifier
.height(25.dp),
verticalAlignment = Alignment.CenterVertically
) {
PlaceholderAtom(width = 70.dp, height = 6.dp)
Spacer(modifier = Modifier.width(6.dp))
PlaceholderAtom(width = 70.dp, height = 6.dp)
}
}
}
}
@Preview
@Composable
internal fun RoomSummaryPlaceholderRowLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun RoomSummaryPlaceholderRowDarkPreview() =
ElementPreviewDark { ContentToPreview() }
@Composable
private fun ContentToPreview() {
RoomSummaryPlaceholderRow()
}

View file

@ -27,7 +27,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
@ -49,7 +48,6 @@ import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.google.accompanist.placeholder.material.placeholder
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
import io.element.android.features.roomlist.impl.model.RoomListRoomSummaryProvider
import io.element.android.libraries.core.extensions.orEmpty
@ -57,15 +55,13 @@ import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAto
import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.theme.ElementTheme
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.roomListPlaceHolder
import io.element.android.libraries.designsystem.theme.roomListRoomMessage
import io.element.android.libraries.designsystem.theme.roomListRoomMessageDate
import io.element.android.libraries.designsystem.theme.roomListRoomName
import io.element.android.libraries.designsystem.theme.roomListUnreadIndicator
private val minHeight = 84.dp
internal val minHeight = 84.dp
@OptIn(ExperimentalFoundationApi::class)
@Composable
@ -75,16 +71,16 @@ internal fun RoomSummaryRow(
onLongClick: (RoomListRoomSummary) -> Unit,
modifier: Modifier = Modifier,
) {
val clickModifier = if (room.isPlaceholder) {
Modifier
} else {
Modifier.combinedClickable(
onClick = { onClick(room) },
onLongClick = { onLongClick(room) },
indication = rememberRipple(),
interactionSource = remember { MutableInteractionSource() }
)
if (room.isPlaceholder) {
RoomSummaryPlaceholderRow(modifier)
return
}
val clickModifier = Modifier.combinedClickable(
onClick = { onClick(room) },
onLongClick = { onLongClick(room) },
indication = rememberRipple(),
interactionSource = remember { MutableInteractionSource() }
)
Row(
modifier = modifier
@ -100,11 +96,6 @@ internal fun RoomSummaryRow(
.avatarData,
modifier = Modifier
.align(Alignment.CenterVertically)
.placeholder(
visible = room.isPlaceholder,
shape = CircleShape,
color = ElementTheme.colors.roomListPlaceHolder(),
)
)
Column(
modifier = Modifier
@ -127,12 +118,7 @@ private fun RowScope.NameAndTimestampRow(room: RoomListRoomSummary) {
Text(
modifier = Modifier
.weight(1f)
.padding(end = 16.dp)
.placeholder(
visible = room.isPlaceholder,
shape = TextPlaceholderShape,
color = ElementTheme.colors.roomListPlaceHolder(),
),
.padding(end = 16.dp),
fontSize = 16.sp,
fontWeight = FontWeight.SemiBold,
style = MaterialTheme.typography.bodyMedium,
@ -143,12 +129,6 @@ private fun RowScope.NameAndTimestampRow(room: RoomListRoomSummary) {
)
// Timestamp
Text(
modifier = Modifier
.placeholder(
visible = room.isPlaceholder,
shape = TextPlaceholderShape,
color = ElementTheme.colors.roomListPlaceHolder(),
),
fontSize = 12.sp,
text = room.timestamp ?: "",
color = MaterialTheme.roomListRoomMessageDate(),
@ -163,12 +143,7 @@ private fun RowScope.LastMessageAndIndicatorRow(room: RoomListRoomSummary) {
Text(
modifier = Modifier
.weight(1f)
.padding(end = 28.dp)
.placeholder(
visible = room.isPlaceholder,
shape = TextPlaceholderShape,
color = ElementTheme.colors.roomListPlaceHolder(),
),
.padding(end = 28.dp),
text = attributedLastMessage,
color = MaterialTheme.roomListRoomMessage(),
fontSize = 14.sp,

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.designsystem.atomic.atoms
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.ElementTheme
import io.element.android.libraries.designsystem.theme.roomListPlaceHolder
@Composable
fun PlaceholderAtom(
width: Dp,
height: Dp,
modifier: Modifier = Modifier,
color: Color = ElementTheme.colors.roomListPlaceHolder(),
) {
Box(
modifier = modifier
.width(width)
.height(height)
.background(
color = color,
shape = RoundedCornerShape(size = height / 2)
)
)
}
@Preview
@Composable
internal fun PlaceholderAtomLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun PlaceholderAtomDarkPreview() =
ElementPreviewDark { ContentToPreview() }
@Composable
private fun ContentToPreview() {
// Use a Red background to see the shape
Box(modifier = Modifier.background(color = Color.Red)) {
PlaceholderAtom(
width = 80.dp,
height = 12.dp
)
}
}

View file

@ -24,8 +24,6 @@ import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.theme.ElementColors
import io.element.android.libraries.theme.ElementTheme
import io.element.android.libraries.theme.SystemGrey4Dark
import io.element.android.libraries.theme.SystemGrey6Light
import io.element.android.libraries.theme.previews.ColorListPreview
import kotlinx.collections.immutable.persistentMapOf
@ -45,7 +43,7 @@ fun MaterialTheme.roomListRoomMessageDate() = colorScheme.secondary
fun MaterialTheme.roomListUnreadIndicator() = colorScheme.primary
@Composable
fun ElementColors.roomListPlaceHolder() = if (isLight) SystemGrey6Light else SystemGrey4Dark
fun ElementColors.roomListPlaceHolder() = if (isLight) Compound_Gray_300_Light else Compound_Gray_300_Dark
@Preview
@Composable