Invite list: various layout tweaks

- Larger avatar
- Include the MXID in the inviter
- Show inviter avatar to the left instead of inline
  (This may be weird in some translations, but it's what design
   wants and is consistent with iOS)
- Pad the name/alias if the notification dot is present
This commit is contained in:
Chris Smith 2023-06-01 16:33:00 +01:00
parent 30e4fad93c
commit b1824c04e5
3 changed files with 46 additions and 56 deletions

View file

@ -17,13 +17,13 @@
package io.element.android.features.invitelist.impl.components package io.element.android.features.invitelist.impl.components
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.IntrinsicSize import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
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
@ -31,18 +31,13 @@ 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.layout.width
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.InlineTextContent
import androidx.compose.foundation.text.appendInlineContent
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
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.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.Placeholder
import androidx.compose.ui.text.PlaceholderVerticalAlign
import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@ -64,8 +59,8 @@ import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.components.Button import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.OutlinedButton import io.element.android.libraries.designsystem.theme.components.OutlinedButton
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.noFontPadding
import io.element.android.libraries.designsystem.theme.roomListUnreadIndicator import io.element.android.libraries.designsystem.theme.roomListUnreadIndicator
import kotlinx.collections.immutable.persistentMapOf
import io.element.android.libraries.ui.strings.R as StringR import io.element.android.libraries.ui.strings.R as StringR
private val minHeight = 72.dp private val minHeight = 72.dp
@ -104,15 +99,17 @@ internal fun DefaultInviteSummaryRow(
verticalAlignment = Alignment.Top verticalAlignment = Alignment.Top
) { ) {
Avatar( Avatar(
invite.roomAvatarData, invite.roomAvatarData.copy(size = AvatarSize.Custom(52.dp)),
) )
Column( Column(
modifier = Modifier modifier = Modifier
.padding(start = 12.dp, end = 4.dp) .padding(start = 16.dp, end = 4.dp)
.alignByBaseline() .alignByBaseline()
.weight(1f) .weight(1f)
) { ) {
val bonusPadding = if (invite.isNew) 12.dp else 0.dp
// Name // Name
Text( Text(
fontSize = 16.sp, fontSize = 16.sp,
@ -120,7 +117,9 @@ internal fun DefaultInviteSummaryRow(
text = invite.roomName, text = invite.roomName,
color = MaterialTheme.colorScheme.primary, color = MaterialTheme.colorScheme.primary,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis,
style = noFontPadding,
modifier = Modifier.padding(end = bonusPadding),
) )
// ID or Alias // ID or Alias
@ -131,7 +130,8 @@ internal fun DefaultInviteSummaryRow(
text = it, text = it,
color = MaterialTheme.colorScheme.secondary, color = MaterialTheme.colorScheme.secondary,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(end = bonusPadding),
) )
} }
@ -173,47 +173,36 @@ internal fun DefaultInviteSummaryRow(
@Composable @Composable
private fun SenderRow(sender: InviteSender) { private fun SenderRow(sender: InviteSender) {
Text( Row(
text = buildAnnotatedString { horizontalArrangement = Arrangement.spacedBy(4.dp),
val placeholder = "$"
val text = stringResource(R.string.screen_invites_invited_you, placeholder)
val nameIndex = text.indexOf(placeholder)
// Text before the placeholder
append(text.take(nameIndex))
// Avatar and display name
appendInlineContent("avatar")
withStyle(SpanStyle(fontWeight = FontWeight.Bold, color = MaterialTheme.colorScheme.primary)) {
append(sender.displayName)
}
// Text after the placeholder
append(text.drop(nameIndex + placeholder.length))
},
color = MaterialTheme.colorScheme.secondary,
fontSize = 14.sp,
fontWeight = FontWeight.Normal,
modifier = Modifier.padding(top = 12.dp), modifier = Modifier.padding(top = 12.dp),
inlineContent = persistentMapOf( ) {
"avatar" to InlineTextContent( Avatar(
with(LocalDensity.current) { avatarData = sender.avatarData.copy(size = AvatarSize.Custom(16.dp)),
Placeholder(20.dp.toSp(), 20.dp.toSp(), PlaceholderVerticalAlign.Center)
}
) {
Box(
Modifier
.fillMaxHeight()
.padding(end = 4.dp)
) {
Avatar(
avatarData = sender.avatarData.copy(size = AvatarSize.Custom(16.dp)),
modifier = Modifier.align(Alignment.Center)
)
}
}
) )
) Text(
text = buildAnnotatedString {
val placeholder = "$"
val text = stringResource(R.string.screen_invites_invited_you, placeholder, sender.userId.value)
val nameIndex = text.indexOf(placeholder)
// Text before the placeholder
append(text.take(nameIndex))
// Display name
withStyle(SpanStyle(fontWeight = FontWeight.Medium, color = MaterialTheme.colorScheme.primary)) {
append(sender.displayName)
}
// Text after the placeholder
append(text.drop(nameIndex + placeholder.length))
},
style = noFontPadding,
color = MaterialTheme.colorScheme.secondary,
fontSize = 14.sp,
fontWeight = FontWeight.Normal,
)
}
} }
@Preview @Preview

View file

@ -24,7 +24,8 @@ open class InviteListInviteSummaryProvider : PreviewParameterProvider<InviteList
override val values: Sequence<InviteListInviteSummary> override val values: Sequence<InviteListInviteSummary>
get() = sequenceOf( get() = sequenceOf(
aInviteListInviteSummary(), aInviteListInviteSummary(),
aInviteListInviteSummary().copy(roomAlias = "#someroom:example.com"), aInviteListInviteSummary().copy(roomAlias = "#someroom-with-a-long-alias:example.com"),
aInviteListInviteSummary().copy(roomAlias = "#someroom-with-a-long-alias:example.com", isNew = true),
aInviteListInviteSummary().copy(roomName = "Alice", sender = null), aInviteListInviteSummary().copy(roomName = "Alice", sender = null),
aInviteListInviteSummary().copy(isNew = true) aInviteListInviteSummary().copy(isNew = true)
) )
@ -32,9 +33,9 @@ open class InviteListInviteSummaryProvider : PreviewParameterProvider<InviteList
fun aInviteListInviteSummary() = InviteListInviteSummary( fun aInviteListInviteSummary() = InviteListInviteSummary(
roomId = RoomId("!room1:example.com"), roomId = RoomId("!room1:example.com"),
roomName = "Some room", roomName = "Some room with a long name that will truncate",
sender = InviteSender( sender = InviteSender(
userId = UserId("@alice:example.org"), userId = UserId("@alice-with-a-long-mxid:example.org"),
displayName = "Alice" displayName = "Alice with a long name"
), ),
) )

View file

@ -5,5 +5,5 @@
<string name="screen_invites_decline_direct_chat_message">"Are you sure you want to decline to chat with %1$s?"</string> <string name="screen_invites_decline_direct_chat_message">"Are you sure you want to decline to chat with %1$s?"</string>
<string name="screen_invites_decline_direct_chat_title">"Decline chat"</string> <string name="screen_invites_decline_direct_chat_title">"Decline chat"</string>
<string name="screen_invites_empty_list">"No Invites"</string> <string name="screen_invites_empty_list">"No Invites"</string>
<string name="screen_invites_invited_you">"%1$s invited you"</string> <string name="screen_invites_invited_you">"%1$s (%2$s) invited you"</string>
</resources> </resources>