design (join room) : update design of join room screen
This commit is contained in:
parent
e79281a78a
commit
c44bf89ed5
12 changed files with 198 additions and 148 deletions
|
|
@ -101,7 +101,6 @@ sealed interface ContentState {
|
|||
|
||||
sealed interface JoinAuthorisationStatus {
|
||||
data object None : JoinAuthorisationStatus
|
||||
data class IsSpace(val applicationName: String) : JoinAuthorisationStatus
|
||||
data class IsInvited(val inviteData: InviteData, val inviteSender: InviteSender?) : JoinAuthorisationStatus
|
||||
data class IsBanned(val banSender: InviteSender?, val reason: String?) : JoinAuthorisationStatus
|
||||
data object IsKnocked : JoinAuthorisationStatus
|
||||
|
|
|
|||
|
|
@ -7,21 +7,20 @@
|
|||
|
||||
package io.element.android.features.joinroom.impl
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
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.sizeIn
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
|
|
@ -38,6 +37,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.features.invite.api.InviteData
|
||||
import io.element.android.libraries.designsystem.atomic.atoms.PlaceholderAtom
|
||||
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewDescriptionAtom
|
||||
|
|
@ -65,14 +65,21 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
|||
import io.element.android.libraries.designsystem.theme.components.Button
|
||||
import io.element.android.libraries.designsystem.theme.components.ButtonSize
|
||||
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.IconSource
|
||||
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.TextButton
|
||||
import io.element.android.libraries.designsystem.theme.components.TextField
|
||||
import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||
import io.element.android.libraries.designsystem.theme.placeholderBackground
|
||||
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
|
||||
import io.element.android.libraries.matrix.ui.components.InviteSenderView
|
||||
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
||||
import io.element.android.libraries.matrix.ui.components.SpaceInfoRow
|
||||
import io.element.android.libraries.matrix.ui.components.SpaceMembersView
|
||||
import io.element.android.libraries.matrix.ui.model.InviteSender
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Composable
|
||||
fun JoinRoomView(
|
||||
|
|
@ -92,7 +99,7 @@ fun JoinRoomView(
|
|||
containerColor = Color.Transparent,
|
||||
contentPadding = PaddingValues(
|
||||
horizontal = 16.dp,
|
||||
vertical = 32.dp
|
||||
vertical = 24.dp
|
||||
),
|
||||
topBar = {
|
||||
JoinRoomTopBar(
|
||||
|
|
@ -220,12 +227,14 @@ private fun JoinRoomFooter(
|
|||
onClick = { onDeclineInvite(joinAuthorisationStatus.inviteData, false) },
|
||||
modifier = Modifier.weight(1f),
|
||||
size = ButtonSize.LargeLowPadding,
|
||||
leadingIcon = IconSource.Vector(CompoundIcons.Close())
|
||||
)
|
||||
Button(
|
||||
text = stringResource(CommonStrings.action_accept),
|
||||
onClick = { onAcceptInvite(joinAuthorisationStatus.inviteData) },
|
||||
modifier = Modifier.weight(1f),
|
||||
size = ButtonSize.LargeLowPadding,
|
||||
leadingIcon = IconSource.Vector(CompoundIcons.Check())
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
|
@ -278,7 +287,6 @@ private fun JoinRoomFooter(
|
|||
JoinAuthorisationStatus.Unknown -> JoinRestrictedFooter(onJoinRoom)
|
||||
JoinAuthorisationStatus.Restricted -> JoinRestrictedFooter(onJoinRoom)
|
||||
JoinAuthorisationStatus.Unauthorized -> JoinUnauthorizedFooter(onGoBack)
|
||||
is JoinAuthorisationStatus.IsSpace -> UnsupportedSpaceFooter(joinAuthorisationStatus.applicationName, onGoBack)
|
||||
JoinAuthorisationStatus.None -> Unit
|
||||
}
|
||||
}
|
||||
|
|
@ -397,19 +405,40 @@ private fun JoinRoomContent(
|
|||
IsKnockedLoadedContent()
|
||||
}
|
||||
else -> {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
val inviteSender = (contentState.joinAuthorisationStatus as? JoinAuthorisationStatus.IsInvited)?.inviteSender
|
||||
if (inviteSender != null) {
|
||||
InviteSenderView(inviteSender = inviteSender, hideAvatarImage = hideAvatarsImages)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
}
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
DefaultLoadedContent(
|
||||
modifier = Modifier.verticalScroll(rememberScrollState()),
|
||||
contentState = contentState,
|
||||
knockMessage = knockMessage,
|
||||
hideAvatarImage = hideAvatarsImages,
|
||||
onKnockMessageUpdate = onKnockMessageUpdate
|
||||
)
|
||||
when (contentState.joinAuthorisationStatus) {
|
||||
is JoinAuthorisationStatus.IsInvited -> {
|
||||
val inviteSender = contentState.joinAuthorisationStatus.inviteSender
|
||||
if (inviteSender != null) {
|
||||
Spacer(Modifier.height(16.dp))
|
||||
InvitedByView(inviteSender, hideAvatarsImages)
|
||||
}
|
||||
}
|
||||
is JoinAuthorisationStatus.CanKnock -> {
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
val supportingText = if (knockMessage.isNotEmpty()) {
|
||||
"${knockMessage.length}/$MAX_KNOCK_MESSAGE_LENGTH"
|
||||
} else {
|
||||
stringResource(R.string.screen_join_room_knock_message_description)
|
||||
}
|
||||
TextField(
|
||||
value = knockMessage,
|
||||
onValueChange = onKnockMessageUpdate,
|
||||
maxLines = 3,
|
||||
minLines = 3,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
supportingText = supportingText
|
||||
)
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -422,6 +451,45 @@ private fun JoinRoomContent(
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun InvitedByView(
|
||||
sender: InviteSender,
|
||||
hideAvatarImage: Boolean,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(
|
||||
modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = "Invited by",
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
color = ElementTheme.colors.textSecondary
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Avatar(
|
||||
avatarData = sender.avatarData,
|
||||
avatarType = AvatarType.User,
|
||||
hideImage = hideAvatarImage,
|
||||
forcedAvatarSize = AvatarSize.RoomPreviewInviter.dp
|
||||
)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
Text(
|
||||
text = sender.displayName,
|
||||
style = ElementTheme.typography.fontBodyLgRegular,
|
||||
color = ElementTheme.colors.textPrimary
|
||||
)
|
||||
Spacer(Modifier.height(4.dp))
|
||||
Text(
|
||||
text = sender.userId.value,
|
||||
style = ElementTheme.typography.fontBodySmRegular,
|
||||
color = ElementTheme.colors.textSecondary
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UnknownRoomContent(
|
||||
modifier: Modifier = Modifier
|
||||
|
|
@ -429,7 +497,21 @@ private fun UnknownRoomContent(
|
|||
RoomPreviewOrganism(
|
||||
modifier = modifier,
|
||||
avatar = {
|
||||
Spacer(modifier = Modifier.size(AvatarSize.RoomHeader.dp))
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(AvatarSize.RoomPreviewHeader.dp)
|
||||
.background(
|
||||
color = ElementTheme.colors.placeholderBackground,
|
||||
shape = CircleShape
|
||||
)
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
tint = ElementTheme.colors.iconPrimary,
|
||||
imageVector = CompoundIcons.VisibilityOff(),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
},
|
||||
title = {
|
||||
RoomPreviewTitleAtom(stringResource(R.string.screen_join_room_title_no_preview))
|
||||
|
|
@ -448,7 +530,7 @@ private fun IncompleteContent(
|
|||
RoomPreviewOrganism(
|
||||
modifier = modifier,
|
||||
avatar = {
|
||||
PlaceholderAtom(width = AvatarSize.RoomHeader.dp, height = AvatarSize.RoomHeader.dp)
|
||||
PlaceholderAtom(width = AvatarSize.RoomPreviewHeader.dp, height = AvatarSize.RoomPreviewHeader.dp)
|
||||
},
|
||||
title = {
|
||||
when (roomIdOrAlias) {
|
||||
|
|
@ -471,43 +553,32 @@ private fun IncompleteContent(
|
|||
|
||||
@Composable
|
||||
private fun IsKnockedLoadedContent(modifier: Modifier = Modifier) {
|
||||
BoxWithConstraints(
|
||||
modifier = modifier
|
||||
.fillMaxHeight()
|
||||
.padding(horizontal = 16.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
IconTitleSubtitleMolecule(
|
||||
modifier = Modifier.sizeIn(minHeight = maxHeight * 0.7f),
|
||||
iconStyle = BigIcon.Style.SuccessSolid,
|
||||
title = stringResource(R.string.screen_join_room_knock_sent_title),
|
||||
subTitle = stringResource(R.string.screen_join_room_knock_sent_description),
|
||||
)
|
||||
}
|
||||
IconTitleSubtitleMolecule(
|
||||
modifier = modifier.padding(horizontal = 8.dp),
|
||||
iconStyle = BigIcon.Style.SuccessSolid,
|
||||
title = stringResource(R.string.screen_join_room_knock_sent_title),
|
||||
subTitle = stringResource(R.string.screen_join_room_knock_sent_description),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DefaultLoadedContent(
|
||||
contentState: ContentState.Loaded,
|
||||
knockMessage: String,
|
||||
hideAvatarImage: Boolean,
|
||||
onKnockMessageUpdate: (String) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
RoomPreviewOrganism(
|
||||
modifier = modifier,
|
||||
avatar = {
|
||||
Avatar(
|
||||
contentState.avatarData(AvatarSize.RoomHeader),
|
||||
contentState.avatarData(AvatarSize.RoomPreviewHeader),
|
||||
hideImage = hideAvatarImage,
|
||||
avatarType = AvatarType.Room(),
|
||||
avatarType = if (contentState.isSpace) AvatarType.Space() else AvatarType.Room(),
|
||||
)
|
||||
},
|
||||
title = {
|
||||
if (contentState.name != null) {
|
||||
RoomPreviewTitleAtom(
|
||||
title = contentState.name,
|
||||
)
|
||||
RoomPreviewTitleAtom(title = contentState.name)
|
||||
} else {
|
||||
RoomPreviewTitleAtom(
|
||||
title = stringResource(id = CommonStrings.common_no_room_name),
|
||||
|
|
@ -516,37 +587,32 @@ private fun DefaultLoadedContent(
|
|||
}
|
||||
},
|
||||
subtitle = {
|
||||
if (contentState.alias != null) {
|
||||
RoomPreviewSubtitleAtom(contentState.alias.value)
|
||||
}
|
||||
},
|
||||
description = {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
RoomPreviewDescriptionAtom(contentState.topic ?: "")
|
||||
if (contentState.joinAuthorisationStatus is JoinAuthorisationStatus.CanKnock) {
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
val supportingText = if (knockMessage.isNotEmpty()) {
|
||||
"${knockMessage.length}/$MAX_KNOCK_MESSAGE_LENGTH"
|
||||
} else {
|
||||
stringResource(R.string.screen_join_room_knock_message_description)
|
||||
}
|
||||
TextField(
|
||||
value = knockMessage,
|
||||
onValueChange = onKnockMessageUpdate,
|
||||
maxLines = 3,
|
||||
minLines = 3,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
supportingText = supportingText
|
||||
when {
|
||||
contentState.isSpace -> {
|
||||
SpaceInfoRow(
|
||||
joinRule = contentState.joinRule ?: JoinRule.Public,
|
||||
numberOfRooms = contentState.childrenCount ?: 0,
|
||||
)
|
||||
}
|
||||
contentState.alias != null -> {
|
||||
RoomPreviewSubtitleAtom(contentState.alias.value)
|
||||
}
|
||||
}
|
||||
},
|
||||
description = {
|
||||
RoomPreviewDescriptionAtom(
|
||||
contentState.topic ?: "",
|
||||
maxLines = if (contentState.joinAuthorisationStatus is JoinAuthorisationStatus.CanJoin) Int.MAX_VALUE else 2
|
||||
)
|
||||
},
|
||||
memberCount = {
|
||||
if (contentState.showMemberCount) {
|
||||
MembersCountMolecule(memberCount = contentState.numberOfMembers?.toInt() ?: 0)
|
||||
val membersCount = contentState.numberOfMembers?.toInt() ?: 0
|
||||
if (contentState.isSpace) {
|
||||
SpaceMembersView(persistentListOf(), membersCount)
|
||||
} else {
|
||||
MembersCountMolecule(memberCount = membersCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -655,7 +655,10 @@ class JoinRoomPresenterTest {
|
|||
isDm = false,
|
||||
roomType = RoomType.Room,
|
||||
roomAvatarUrl = "avatarUrl",
|
||||
joinAuthorisationStatus = JoinAuthorisationStatus.CanJoin
|
||||
joinAuthorisationStatus = JoinAuthorisationStatus.CanJoin,
|
||||
joinRule = JoinRule.Public,
|
||||
childrenCount = null,
|
||||
heroes = persistentListOf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -724,7 +727,10 @@ class JoinRoomPresenterTest {
|
|||
),
|
||||
membershipChangeReason = null,
|
||||
),
|
||||
)
|
||||
),
|
||||
joinRule = JoinRule.Public,
|
||||
childrenCount = null,
|
||||
heroes = persistentListOf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -789,7 +795,10 @@ class JoinRoomPresenterTest {
|
|||
membershipChangeReason = null,
|
||||
),
|
||||
reason = null,
|
||||
)
|
||||
),
|
||||
joinRule = JoinRule.Public,
|
||||
childrenCount = null,
|
||||
heroes = persistentListOf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -842,7 +851,10 @@ class JoinRoomPresenterTest {
|
|||
isDm = false,
|
||||
roomType = RoomType.Room,
|
||||
roomAvatarUrl = "avatarUrl",
|
||||
joinAuthorisationStatus = JoinAuthorisationStatus.IsKnocked
|
||||
joinAuthorisationStatus = JoinAuthorisationStatus.IsKnocked,
|
||||
joinRule = JoinRule.Public,
|
||||
childrenCount = null,
|
||||
heroes = persistentListOf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -949,26 +961,6 @@ class JoinRoomPresenterTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - when room is not known RoomPreview is loaded as Space`() = runTest {
|
||||
val client = FakeMatrixClient(
|
||||
getNotJoinedRoomResult = { _, _ ->
|
||||
Result.success(
|
||||
aRoomPreview(info = aRoomPreviewInfo(isSpace = true))
|
||||
)
|
||||
}
|
||||
)
|
||||
val presenter = createJoinRoomPresenter(
|
||||
matrixClient = client
|
||||
)
|
||||
presenter.test {
|
||||
skipItems(1)
|
||||
awaitItem().also { state ->
|
||||
assertThat(state.joinAuthorisationStatus).isEqualTo(JoinAuthorisationStatus.UnsupportedSpace("AppName"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - when room is not known RoomPreview is loaded with error`() = runTest {
|
||||
val client = FakeMatrixClient(
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ private fun RoomAliasResolverContent(
|
|||
RoomPreviewOrganism(
|
||||
modifier = modifier,
|
||||
avatar = {
|
||||
PlaceholderAtom(width = AvatarSize.RoomHeader.dp, height = AvatarSize.RoomHeader.dp)
|
||||
PlaceholderAtom(width = AvatarSize.RoomPreviewHeader.dp, height = AvatarSize.RoomPreviewHeader.dp)
|
||||
},
|
||||
title = {
|
||||
RoomPreviewSubtitleAtom(roomAlias.value)
|
||||
|
|
|
|||
|
|
@ -396,10 +396,10 @@ private fun RoomHeaderSection(
|
|||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Avatar(
|
||||
avatarData = AvatarData(roomId.value, roomName, avatarUrl, AvatarSize.RoomHeader),
|
||||
avatarData = AvatarData(roomId.value, roomName, avatarUrl, AvatarSize.RoomDetailsHeader),
|
||||
avatarType = AvatarType.Room(
|
||||
heroes = heroes.map { user ->
|
||||
user.getAvatarData(size = AvatarSize.RoomHeader)
|
||||
user.getAvatarData(size = AvatarSize.RoomDetailsHeader)
|
||||
}.toPersistentList(),
|
||||
isTombstoned = isTombstoned,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -15,14 +15,18 @@ import io.element.android.compound.theme.ElementTheme
|
|||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
|
||||
@Composable
|
||||
fun RoomPreviewDescriptionAtom(description: String, modifier: Modifier = Modifier) {
|
||||
fun RoomPreviewDescriptionAtom(
|
||||
description: String,
|
||||
modifier: Modifier = Modifier,
|
||||
maxLines: Int = Int.MAX_VALUE,
|
||||
) {
|
||||
Text(
|
||||
modifier = modifier,
|
||||
text = description,
|
||||
style = ElementTheme.typography.fontBodySmRegular,
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
textAlign = TextAlign.Center,
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
maxLines = 3,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
maxLines = maxLines,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ fun RoomPreviewSubtitleAtom(subtitle: String, modifier: Modifier = Modifier) {
|
|||
Text(
|
||||
modifier = modifier,
|
||||
text = subtitle,
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
style = ElementTheme.typography.fontBodyLgRegular,
|
||||
textAlign = TextAlign.Center,
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ fun RoomPreviewTitleAtom(
|
|||
Text(
|
||||
modifier = modifier,
|
||||
text = title,
|
||||
style = ElementTheme.typography.fontHeadingMdBold,
|
||||
style = ElementTheme.typography.fontHeadingLgBold,
|
||||
textAlign = TextAlign.Center,
|
||||
fontStyle = fontStyle,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
|
|
|
|||
|
|
@ -34,14 +34,13 @@ fun RoomPreviewOrganism(
|
|||
title()
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
subtitle()
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
if (memberCount != null) {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
memberCount()
|
||||
}
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
if (description != null) {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
description()
|
||||
}
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ enum class AvatarSize(val dp: Dp) {
|
|||
CurrentUserTopBar(32.dp),
|
||||
|
||||
IncomingCall(140.dp),
|
||||
RoomHeader(96.dp),
|
||||
RoomDetailsHeader(96.dp),
|
||||
RoomListItem(52.dp),
|
||||
|
||||
SpaceListItem(52.dp),
|
||||
|
|
@ -68,5 +68,7 @@ enum class AvatarSize(val dp: Dp) {
|
|||
|
||||
OrganizationHeader(64.dp),
|
||||
SpaceHeader(64.dp),
|
||||
RoomPreviewHeader(64.dp),
|
||||
RoomPreviewInviter(56.dp),
|
||||
SpaceMember(24.dp),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,19 +7,14 @@
|
|||
|
||||
package io.element.android.libraries.matrix.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewDescriptionAtom
|
||||
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewTitleAtom
|
||||
import io.element.android.libraries.designsystem.atomic.organisms.RoomPreviewOrganism
|
||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
|
|
@ -47,47 +42,40 @@ fun SpaceHeaderView(
|
|||
modifier: Modifier = Modifier,
|
||||
topicMaxLines: Int = Int.MAX_VALUE,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 32.dp, bottom = 24.dp, start = 16.dp, end = 16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Avatar(
|
||||
avatarData = avatarData,
|
||||
avatarType = AvatarType.Space(false),
|
||||
)
|
||||
name?.let {
|
||||
Text(
|
||||
text = name,
|
||||
style = ElementTheme.typography.fontHeadingLgBold,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
textAlign = TextAlign.Center,
|
||||
RoomPreviewOrganism(
|
||||
modifier = modifier.padding(24.dp),
|
||||
avatar = {
|
||||
Avatar(
|
||||
avatarData = avatarData,
|
||||
avatarType = AvatarType.Space(),
|
||||
)
|
||||
}
|
||||
if (joinRule != null) {
|
||||
SpaceInfoRow(
|
||||
joinRule = joinRule,
|
||||
numberOfRooms = numberOfRooms,
|
||||
},
|
||||
title = {
|
||||
name?.let {
|
||||
RoomPreviewTitleAtom(title = name)
|
||||
}
|
||||
},
|
||||
subtitle = {
|
||||
if (joinRule != null) {
|
||||
SpaceInfoRow(
|
||||
joinRule = joinRule,
|
||||
numberOfRooms = numberOfRooms,
|
||||
)
|
||||
}
|
||||
},
|
||||
description = if (topic != null) {
|
||||
{ RoomPreviewDescriptionAtom(description = topic, maxLines = topicMaxLines) }
|
||||
} else {
|
||||
null
|
||||
},
|
||||
memberCount = {
|
||||
SpaceMembersView(
|
||||
heroes = heroes,
|
||||
numberOfMembers = numberOfMembers,
|
||||
modifier = Modifier.padding(horizontal = 32.dp),
|
||||
)
|
||||
}
|
||||
SpaceMembersView(
|
||||
heroes = heroes,
|
||||
numberOfMembers = numberOfMembers,
|
||||
modifier = Modifier.padding(horizontal = 32.dp),
|
||||
)
|
||||
topic?.let {
|
||||
Text(
|
||||
text = topic,
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = topicMaxLines,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ class DefaultNotificationConversationService(
|
|||
targetSize = defaultShortcutIconSize.toLong()
|
||||
)?.let(IconCompat::createWithBitmap)
|
||||
?: InitialsAvatarBitmapGenerator(useDarkTheme = useDarkTheme)
|
||||
.generateBitmap(defaultShortcutIconSize, AvatarData(id = roomId.value, name = roomName, size = AvatarSize.RoomHeader))
|
||||
.generateBitmap(defaultShortcutIconSize, AvatarData(id = roomId.value, name = roomName, size = AvatarSize.RoomDetailsHeader))
|
||||
?.let(IconCompat::createWithAdaptiveBitmap)
|
||||
|
||||
val shortcutInfo = ShortcutInfoCompat.Builder(context, createShortcutId(sessionId, roomId))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue