diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt index 36a74c813e..6ecdcf4ba2 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt @@ -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 diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt index 03598425e9..af4665e5da 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomView.kt @@ -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) + } } } ) diff --git a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt index 5a6631146d..6deb39fba4 100644 --- a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt +++ b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt @@ -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( diff --git a/features/roomaliasresolver/impl/src/main/kotlin/io/element/android/features/roomaliasresolver/impl/RoomAliasResolverView.kt b/features/roomaliasresolver/impl/src/main/kotlin/io/element/android/features/roomaliasresolver/impl/RoomAliasResolverView.kt index ef2cc47ecc..9d7536b2f5 100644 --- a/features/roomaliasresolver/impl/src/main/kotlin/io/element/android/features/roomaliasresolver/impl/RoomAliasResolverView.kt +++ b/features/roomaliasresolver/impl/src/main/kotlin/io/element/android/features/roomaliasresolver/impl/RoomAliasResolverView.kt @@ -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) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index 3fdb2a0800..61d5ba115a 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -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, ), diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewDescriptionAtom.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewDescriptionAtom.kt index 8ca1a01e6b..3aece9889e 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewDescriptionAtom.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewDescriptionAtom.kt @@ -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, ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewSubtitleAtom.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewSubtitleAtom.kt index ae705e6bfb..4fe52f5443 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewSubtitleAtom.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewSubtitleAtom.kt @@ -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, ) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewTitleAtom.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewTitleAtom.kt index 2ede537931..2c77dc8461 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewTitleAtom.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RoomPreviewTitleAtom.kt @@ -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, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/organisms/RoomPreviewOrganism.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/organisms/RoomPreviewOrganism.kt index 511eb298ea..dac9f00a7c 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/organisms/RoomPreviewOrganism.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/organisms/RoomPreviewOrganism.kt @@ -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)) } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt index 9e9ebb6181..b7d6339d02 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt @@ -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), } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderView.kt index 11e9f37c8b..ecfde229c9 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/SpaceHeaderView.kt @@ -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 diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/conversations/DefaultNotificationConversationService.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/conversations/DefaultNotificationConversationService.kt index 24b69a2e58..bda5a593d5 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/conversations/DefaultNotificationConversationService.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/conversations/DefaultNotificationConversationService.kt @@ -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))