@ -9,21 +9,31 @@ package io.element.android.features.joinroom.impl
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.PaddingValues
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.fillMaxSize
import androidx.compose.foundation.layout.fillMaxSize
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.padding
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3Api
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.graphics.Color
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.theme.ElementTheme
@ -32,20 +42,25 @@ import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewDescrip
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewSubtitleAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewSubtitleAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewTitleAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewTitleAtom
import io.element.android.libraries.designsystem.atomic.molecules.ButtonRowMolecule
import io.element.android.libraries.designsystem.atomic.molecules.ButtonRowMolecule
import io.element.android.libraries.designsystem.atomic.molecules.IconTitlePlaceholdersRowMolecule
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.atomic.molecules.RoomPreviewMembersCountMolecule
import io.element.android.libraries.designsystem.atomic.molecules.RoomPreviewMembersCountMolecule
import io.element.android.libraries.designsystem.atomic.organisms.RoomPreviewOrganism
import io.element.android.libraries.designsystem.atomic.organisms.RoomPreviewOrganism
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
import io.element.android.libraries.designsystem.background.LightGradientBackground
import io.element.android.libraries.designsystem.background.LightGradientBackground
import io.element.android.libraries.designsystem.components.BigIcon
import io.element.android.libraries.designsystem.components.async.AsyncActionView
import io.element.android.libraries.designsystem.components.async.AsyncActionView
import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.button.SuperButton
import io.element.android.libraries.designsystem.components.button.SuperButton
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
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.Button
import io.element.android.libraries.designsystem.theme.components.ButtonSize
import io.element.android.libraries.designsystem.theme.components.ButtonSize
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.OutlinedTextField
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.components.TopAppBar
import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
@ -59,6 +74,7 @@ fun JoinRoomView(
onBackClick : ( ) -> Unit ,
onBackClick : ( ) -> Unit ,
onJoinSuccess : ( ) -> Unit ,
onJoinSuccess : ( ) -> Unit ,
onKnockSuccess : ( ) -> Unit ,
onKnockSuccess : ( ) -> Unit ,
onCancelKnockSuccess : ( ) -> Unit ,
modifier : Modifier = Modifier ,
modifier : Modifier = Modifier ,
) {
) {
Box (
Box (
@ -69,12 +85,14 @@ fun JoinRoomView(
containerColor = Color . Transparent ,
containerColor = Color . Transparent ,
paddingValues = PaddingValues ( 16. dp ) ,
paddingValues = PaddingValues ( 16. dp ) ,
topBar = {
topBar = {
JoinRoomTopBar ( onBackClick = onBackClick )
JoinRoomTopBar ( contentState = state . contentState , onBackClick = onBackClick )
} ,
} ,
content = {
content = {
JoinRoomContent (
JoinRoomContent (
contentState = state . contentState ,
contentState = state . contentState ,
applicationName = state . applicationName ,
applicationName = state . applicationName ,
knockMessage = state . knockMessage ,
onKnockMessageUpdate = { state . eventSink ( JoinRoomEvents . UpdateKnockMessage ( it ) ) } ,
)
)
} ,
} ,
footer = {
footer = {
@ -92,6 +110,9 @@ fun JoinRoomView(
onKnockRoom = {
onKnockRoom = {
state . eventSink ( JoinRoomEvents . KnockRoom )
state . eventSink ( JoinRoomEvents . KnockRoom )
} ,
} ,
onCancelKnock = {
state . eventSink ( JoinRoomEvents . CancelKnock ( requiresConfirmation = true ) )
} ,
onRetry = {
onRetry = {
state . eventSink ( JoinRoomEvents . RetryFetchingContent )
state . eventSink ( JoinRoomEvents . RetryFetchingContent )
} ,
} ,
@ -103,12 +124,30 @@ fun JoinRoomView(
AsyncActionView (
AsyncActionView (
async = state . joinAction ,
async = state . joinAction ,
onSuccess = { onJoinSuccess ( ) } ,
onSuccess = { onJoinSuccess ( ) } ,
onErrorDismiss = { state . eventSink ( JoinRoomEvents . ClearError ) } ,
onErrorDismiss = { state . eventSink ( JoinRoomEvents . ClearActionStates ) } ,
)
)
AsyncActionView (
AsyncActionView (
async = state . knockAction ,
async = state . knockAction ,
onSuccess = { onKnockSuccess ( ) } ,
onSuccess = { onKnockSuccess ( ) } ,
onErrorDismiss = { state . eventSink ( JoinRoomEvents . ClearError ) } ,
onErrorDismiss = { state . eventSink ( JoinRoomEvents . ClearActionStates ) } ,
)
AsyncActionView (
async = state . cancelKnockAction ,
onSuccess = { onCancelKnockSuccess ( ) } ,
onErrorDismiss = { state . eventSink ( JoinRoomEvents . ClearActionStates ) } ,
errorMessage = {
stringResource ( CommonStrings . error _unknown )
} ,
confirmationDialog = {
ConfirmationDialog (
content = stringResource ( R . string . screen _join _room _cancel _knock _alert _description ) ,
title = stringResource ( R . string . screen _join _room _cancel _knock _alert _title ) ,
submitText = stringResource ( R . string . screen _join _room _cancel _knock _alert _confirmation ) ,
cancelText = stringResource ( CommonStrings . action _no ) ,
onSubmitClick = { state . eventSink ( JoinRoomEvents . CancelKnock ( requiresConfirmation = false ) ) } ,
onDismiss = { state . eventSink ( JoinRoomEvents . ClearActionStates ) } ,
)
} ,
)
)
}
}
@ -119,63 +158,81 @@ private fun JoinRoomFooter(
onDeclineInvite : ( ) -> Unit ,
onDeclineInvite : ( ) -> Unit ,
onJoinRoom : ( ) -> Unit ,
onJoinRoom : ( ) -> Unit ,
onKnockRoom : ( ) -> Unit ,
onKnockRoom : ( ) -> Unit ,
onCancelKnock : ( ) -> Unit ,
onRetry : ( ) -> Unit ,
onRetry : ( ) -> Unit ,
onGoBack : ( ) -> Unit ,
onGoBack : ( ) -> Unit ,
modifier : Modifier = Modifier ,
modifier : Modifier = Modifier ,
) {
) {
if ( state . contentState is ContentState . Failure ) {
Box (
Button (
modifier = modifier
text = stringResource ( CommonStrings . action _retry ) ,
. fillMaxWidth ( )
onClick = onRetry ,
. padding ( top = 8. dp )
modifier = modifier . fillMaxWidth ( ) ,
) {
size = ButtonSize . Large ,
if ( state . contentState is ContentState . Failure ) {
)
Button (
} else if ( state . contentState is ContentState . Loaded && state . contentState . roomType == RoomType . Space ) {
text = stringResource ( CommonStrings . action _retry ) ,
Button (
onClick = onRetry ,
text = stringResource ( CommonStrings . action _go _back ) ,
modifier = Modifier . fillMaxWidth ( ) ,
onClick = onGoBack ,
size = ButtonSize . Large ,
modifier = modifier . fillMaxWidth ( ) ,
)
size = ButtonSize . Large ,
} else if ( state . contentState is ContentState . Loaded && state . contentState . roomType == RoomType . Space ) {
)
Button (
} else {
text = stringResource ( CommonStrings . action _go _back ) ,
val joinAuthorisationStatus = state . joinAuthorisationStatus
onClick = onGoBack ,
when ( joinAuthorisationStatus ) {
modifier = Modifier . fillMaxWidth ( ) ,
is JoinAuthorisationStatus . IsInvited -> {
size = ButtonSize . Large ,
ButtonRowMolecule ( modifier = modifier , horizontalArrangement = Arrangement . spacedBy ( 20. dp ) ) {
)
OutlinedButton (
} else {
text = stringResource ( CommonStrings . action _decline ) ,
val joinAuthorisationStatus = state . joinAuthorisationStatus
onClick = onDeclineInvite ,
when ( joinAuthorisationStatus ) {
modifier = Modifier . weight ( 1f ) ,
is JoinAuthorisationStatus . IsInvited -> {
size = ButtonSize . LargeLowPadding ,
ButtonRowMolecule ( horizontalArrangement = Arrangement . spacedBy ( 20. dp ) ) {
)
OutlinedButton (
Button (
text = stringResource ( CommonStrings . action _decline ) ,
text = stringResource ( CommonStrings . action _accept ) ,
onClick = onDeclineInvite ,
onClick = onAcceptInvite ,
modifier = Modifier . weight ( 1f ) ,
modifier = Modifier . weight ( 1f ) ,
size = ButtonSize . LargeLowPadding ,
size = ButtonSize . LargeLowPadding ,
)
)
Button (
text = stringResource ( CommonStrings . action _accept ) ,
onClick = onAcceptInvite ,
modifier = Modifier . weight ( 1f ) ,
size = ButtonSize . LargeLowPadding ,
)
}
}
}
}
JoinAuthorisationStatus . CanJoin -> {
JoinAuthorisationStatus . CanJoin -> {
SuperButton (
SuperButton (
onClick = onJoinRoom ,
onClick = onJoinRoom ,
modifier = Modifier . fillMaxWidth ( ) ,
modifier = modifier . fillMaxWidth ( ) ,
buttonSize = ButtonSize . Large ,
buttonSize = ButtonSize . Large ,
) {
) {
Text (
Text (
text = stringResource ( R . string . screen _join _room _join _action ) ,
text = stringResource ( R . string . screen _join _room _join _action ) ,
)
}
}
JoinAuthorisationStatus . CanKnock -> {
SuperButton (
onClick = onKnockRoom ,
modifier = Modifier . fillMaxWidth ( ) ,
buttonSize = ButtonSize . Large ,
) {
Text (
text = stringResource ( R . string . screen _join _room _knock _action ) ,
)
}
}
JoinAuthorisationStatus . IsKnocked -> {
OutlinedButton (
text = stringResource ( R . string . screen _join _room _cancel _knock _action ) ,
onClick = onCancelKnock ,
modifier = Modifier . fillMaxWidth ( ) ,
size = ButtonSize . Large ,
)
)
}
}
JoinAuthorisationStatus . Unknown -> Unit
}
}
JoinAuthorisationStatus . CanKnock -> {
Button (
text = stringResource ( R . string . screen _join _room _knock _action ) ,
onClick = onKnockRoom ,
modifier = modifier . fillMaxWidth ( ) ,
size = ButtonSize . Large ,
)
}
JoinAuthorisationStatus . Unknown -> Unit
}
}
}
}
}
}
@ -184,132 +241,217 @@ private fun JoinRoomFooter(
private fun JoinRoomContent (
private fun JoinRoomContent (
contentState : ContentState ,
contentState : ContentState ,
applicationName : String ,
applicationName : String ,
knockMessage : String ,
onKnockMessageUpdate : ( String ) -> Unit ,
modifier : Modifier = Modifier ,
modifier : Modifier = Modifier ,
) {
) {
when ( contentState ) {
Box ( modifier = modifier ) {
is ContentState . Loaded -> {
when ( contentState ) {
RoomPreviewOrganism (
is ContentState . Loaded -> {
modifier = modifier ,
when ( contentState . joinAuthorisationStatus ) {
avatar = {
is JoinAuthorisationStatus . IsKnocked -> {
Avatar ( contentState . avatarData ( AvatarSize . RoomHeader ) )
IsKnockedLoadedContent ( )
} ,
title = {
if ( contentState . name != null ) {
RoomPreviewTitleAtom (
title = contentState . name ,
)
} else {
RoomPreviewTitleAtom (
title = stringResource ( id = CommonStrings . common _no _room _name ) ,
fontStyle = FontStyle . Italic
)
}
} ,
subtitle = {
if ( contentState . alias != null ) {
RoomPreviewSubtitleAtom ( contentState . alias . value )
}
}
} ,
else -> {
description = {
DefaultLoadedContent (
Column (
modifier = Modifier . verticalScroll ( rememberScrollState ( ) ) ,
horizontalAlignment = Alignment . CenterHorizontally ,
contentState = contentState ,
verticalArrangement = Arrangement . spacedBy ( 8. dp ) ,
applicationName = applicationName ,
) {
knockMessage = knockMessage ,
val inviteSender = ( contentState . joinAuthorisationStatus as ? JoinAuthorisationStatus . IsInvited ) ?. inviteSender
onKnockMessageUpdate = onKnockMessageUpdate
if ( inviteSender != null ) {
)
InviteSenderView ( inviteSender = inviteSender )
}
RoomPreviewDescriptionAtom ( contentState . topic ?: " " )
if ( contentState . roomType == RoomType . Space ) {
Spacer ( modifier = Modifier . height ( 24. dp ) )
Text (
text = stringResource ( R . string . screen _join _room _space _not _supported _title ) ,
textAlign = TextAlign . Center ,
style = ElementTheme . typography . fontBodyLgMedium ,
color = MaterialTheme . colorScheme . primary ,
)
Text (
text = stringResource ( R . string . screen _join _room _space _not _supported _description , applicationName ) ,
textAlign = TextAlign . Center ,
style = ElementTheme . typography . fontBodyMdRegular ,
color = MaterialTheme . colorScheme . secondary ,
)
}
}
} ,
memberCount = {
if ( contentState . showMemberCount ) {
RoomPreviewMembersCountMolecule ( memberCount = contentState . numberOfMembers ?: 0 )
}
}
}
}
)
}
}
is ContentState . UnknownRoom -> {
is ContentState . UnknownRoom -> {
RoomPreviewOrganism (
RoomPreviewOrganism (
avatar = {
modifier = modifier ,
PlaceholderAtom ( width = AvatarSize . RoomHeader . dp , height = AvatarSize . RoomHeader . dp )
avatar = {
} ,
PlaceholderAtom ( width = AvatarSize . RoomHeader . dp , height = AvatarSize . RoomHeader . dp )
title = {
} ,
RoomPreviewTitleAtom ( stringResource ( R . string . screen _join _room _title _no _preview ) )
title = {
} ,
RoomPreviewTitleAtom ( stringResource ( R . string . screen _join _room _title _no _preview ) )
subtitle = {
} ,
RoomPreviewSubtitleAtom ( stringResource ( R . string . screen _join _room _subtitle _no _preview ) )
subtitle = {
} ,
RoomPreviewSubtitleAtom ( stringResource ( R . string . screen _join _room _subtitle _no _preview ) )
)
} ,
}
)
is ContentState . Loading -> {
}
RoomPreviewOrganism (
is ContentState . Loading -> {
avatar = {
RoomPreviewOrganism (
PlaceholderAtom ( width = AvatarSize . RoomHeader . dp , height = AvatarSize . RoomHeader . dp )
modifier = modifier ,
} ,
avatar = {
title = {
PlaceholderAtom ( width = AvatarSize . RoomHeader . dp , height = AvatarSize . RoomHeader . dp )
PlaceholderAtom ( width = 200. dp , height = 22. dp )
} ,
} ,
title = {
subtitle = {
PlaceholderAtom ( width = 200. dp , height = 22. dp )
PlaceholderAtom ( width = 140. dp , height = 20. dp )
} ,
} ,
subtitle = {
)
PlaceholderAtom ( width = 140. dp , height = 20. dp )
}
} ,
is ContentState . Failure -> {
)
RoomPreviewOrganism (
}
avatar = {
is ContentState . Failure -> {
PlaceholderAtom ( width = AvatarSize . RoomHeader . dp , height = AvatarSize . RoomHeader . dp )
RoomPreviewOrganism (
} ,
modifier = modifier ,
title = {
avatar = {
when ( contentState . roomIdOrAlias ) {
PlaceholderAtom ( width = AvatarSize . RoomHeader . dp , height = AvatarSize . RoomHeader . dp )
is RoomIdOrAlias . Alias -> {
} ,
RoomPreviewTitleAtom ( contentState . roomIdOrAlias . identifier )
title = {
}
when ( contentState . roomIdOrAlias ) {
is RoomIdOrAlias . Id -> {
is RoomIdOrAlias . Alias -> {
PlaceholderAtom ( width = 200. dp , height = 22. dp )
RoomPreviewTitleAtom ( contentState . roomIdOrAlias . identifier )
}
}
is RoomIdOrAlias . Id -> {
PlaceholderAtom ( width = 200. dp , height = 22. dp )
}
}
}
} ,
} ,
subtitle = {
subtitle = {
Text (
text = stringResource ( id = CommonStrings . error _unknown ) ,
textAlign = TextAlign . Center ,
color = MaterialTheme . colorScheme . error ,
)
} ,
)
}
}
}
}
@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 ) ,
)
}
}
@Composable
private fun DefaultLoadedContent (
contentState : ContentState . Loaded ,
applicationName : String ,
knockMessage : String ,
onKnockMessageUpdate : ( String ) -> Unit ,
modifier : Modifier = Modifier ,
) {
RoomPreviewOrganism (
modifier = modifier ,
avatar = {
Avatar ( contentState . avatarData ( AvatarSize . RoomHeader ) )
} ,
title = {
if ( contentState . name != null ) {
RoomPreviewTitleAtom (
title = contentState . name ,
)
} else {
RoomPreviewTitleAtom (
title = stringResource ( id = CommonStrings . common _no _room _name ) ,
fontStyle = FontStyle . Italic
)
}
} ,
subtitle = {
if ( contentState . alias != null ) {
RoomPreviewSubtitleAtom ( contentState . alias . value )
}
} ,
description = {
Column (
horizontalAlignment = Alignment . CenterHorizontally ,
verticalArrangement = Arrangement . spacedBy ( 8. dp ) ,
) {
val inviteSender = ( contentState . joinAuthorisationStatus as ? JoinAuthorisationStatus . IsInvited ) ?. inviteSender
if ( inviteSender != null ) {
InviteSenderView ( inviteSender = inviteSender )
}
RoomPreviewDescriptionAtom ( contentState . topic ?: " " )
if ( contentState . roomType == RoomType . Space ) {
Spacer ( modifier = Modifier . height ( 24. dp ) )
Text (
Text (
text = stringResource ( id = CommonStrings . error _unknown ) ,
text = stringResource ( R . string . screen _join _room _space _not _supported _title ) ,
textAlign = TextAlign . Center ,
textAlign = TextAlign . Center ,
color = MaterialTheme . colorScheme . error ,
style = ElementTheme . typography . fontBodyLgMedium ,
color = MaterialTheme . colorScheme . primary ,
)
)
} ,
Text (
)
text = stringResource ( R . string . screen _join _room _space _not _supported _description , applicationName ) ,
textAlign = TextAlign . Center ,
style = ElementTheme . typography . fontBodyMdRegular ,
color = MaterialTheme . colorScheme . secondary ,
)
} else if ( contentState . joinAuthorisationStatus is JoinAuthorisationStatus . CanKnock ) {
Spacer ( modifier = Modifier . height ( 24. dp ) )
OutlinedTextField (
value = knockMessage ,
onValueChange = onKnockMessageUpdate ,
maxLines = 3 ,
minLines = 3 ,
modifier = Modifier . fillMaxWidth ( )
)
Text (
text = stringResource ( R . string . screen _join _room _knock _message _description ) ,
style = ElementTheme . typography . fontBodySmRegular ,
color = ElementTheme . colors . textPlaceholder ,
textAlign = TextAlign . Start ,
modifier = Modifier . fillMaxWidth ( )
)
}
}
} ,
memberCount = {
if ( contentState . showMemberCount ) {
RoomPreviewMembersCountMolecule ( memberCount = contentState . numberOfMembers ?: 0 )
}
}
}
}
)
}
}
@OptIn ( ExperimentalMaterial3Api :: class )
@OptIn ( ExperimentalMaterial3Api :: class )
@Composable
@Composable
private fun JoinRoomTopBar (
private fun JoinRoomTopBar (
contentState : ContentState ,
onBackClick : ( ) -> Unit ,
onBackClick : ( ) -> Unit ,
) {
) {
TopAppBar (
TopAppBar (
navigationIcon = {
navigationIcon = {
BackButton ( onClick = onBackClick )
BackButton ( onClick = onBackClick )
} ,
} ,
title = { } ,
title = {
if ( contentState is ContentState . Loaded && contentState . joinAuthorisationStatus is JoinAuthorisationStatus . IsKnocked ) {
val roundedCornerShape = RoundedCornerShape ( 8. dp )
val titleModifier = Modifier
. clip ( roundedCornerShape )
if ( contentState . name != null ) {
Row (
modifier = titleModifier ,
verticalAlignment = Alignment . CenterVertically
) {
Avatar ( avatarData = contentState . avatarData ( AvatarSize . TimelineRoom ) )
Text (
modifier = Modifier . padding ( horizontal = 8. dp ) ,
text = contentState . name ,
style = ElementTheme . typography . fontBodyLgMedium ,
maxLines = 1 ,
overflow = TextOverflow . Ellipsis
)
}
} else {
IconTitlePlaceholdersRowMolecule (
iconSize = AvatarSize . TimelineRoom . dp ,
modifier = titleModifier
)
}
}
} ,
)
)
}
}
@ -321,5 +463,6 @@ internal fun JoinRoomViewPreview(@PreviewParameter(JoinRoomStateProvider::class)
onBackClick = { } ,
onBackClick = { } ,
onJoinSuccess = { } ,
onJoinSuccess = { } ,
onKnockSuccess = { } ,
onKnockSuccess = { } ,
onCancelKnockSuccess = { } ,
)
)
}
}