change(room details) : update room details with new sections organisation

This commit is contained in:
ganfra
2025-01-17 13:05:25 +01:00
parent 0856a9ac62
commit 1aa0afd280
4 changed files with 85 additions and 67 deletions

View File

@@ -33,6 +33,7 @@ import io.element.android.features.roomdetails.impl.members.RoomMemberListNode
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsNode
import io.element.android.features.roomdetails.impl.notificationsettings.RoomNotificationSettingsNode
import io.element.android.features.roomdetails.impl.rolesandpermissions.RolesAndPermissionsFlowNode
import io.element.android.features.roomdetails.impl.securityandprivacy.SecurityAndPrivacyNode
import io.element.android.features.userprofile.shared.UserProfileNodeHelper
import io.element.android.libraries.architecture.BackstackWithOverlayBox
import io.element.android.libraries.architecture.BaseFlowNode
@@ -114,6 +115,9 @@ class RoomDetailsFlowNode @AssistedInject constructor(
@Parcelize
data object KnockRequestsList : NavTarget
@Parcelize
data object SecurityAndPrivacy : NavTarget
}
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
@@ -160,6 +164,10 @@ class RoomDetailsFlowNode @AssistedInject constructor(
backstack.push(NavTarget.KnockRequestsList)
}
override fun openSecurityAndPrivacy() {
backstack.push(NavTarget.SecurityAndPrivacy)
}
override fun onJoinCall() {
val inputs = CallType.RoomCall(
sessionId = room.sessionId,
@@ -290,6 +298,9 @@ class RoomDetailsFlowNode @AssistedInject constructor(
NavTarget.KnockRequestsList -> {
knockRequestsListEntryPoint.createNode(this, buildContext)
}
NavTarget.SecurityAndPrivacy -> {
createNode<SecurityAndPrivacyNode>(buildContext)
}
}
}

View File

@@ -49,6 +49,7 @@ class RoomDetailsNode @AssistedInject constructor(
fun openAdminSettings()
fun openPinnedMessagesList()
fun openKnockRequestsList()
fun openSecurityAndPrivacy()
fun onJoinCall()
}
@@ -121,6 +122,10 @@ class RoomDetailsNode @AssistedInject constructor(
callbacks.forEach { it.openKnockRequestsList() }
}
private fun openSecurityAndPrivacy() {
callbacks.forEach { it.openSecurityAndPrivacy() }
}
@Composable
override fun View(modifier: Modifier) {
val context = LocalContext.current
@@ -153,6 +158,7 @@ class RoomDetailsNode @AssistedInject constructor(
onJoinCallClick = ::onJoinCall,
onPinnedMessagesClick = ::openPinnedMessages,
onKnockRequestsClick = ::openKnockRequestsLists,
onSecurityAndPrivacyClick = ::openSecurityAndPrivacy
)
}
}

View File

@@ -12,7 +12,6 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.consumeWindowInsets
@@ -73,7 +72,6 @@ import io.element.android.libraries.designsystem.theme.components.ListItemStyle
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.designsystem.utils.CommonDrawables
import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.RoomMember
@@ -106,6 +104,7 @@ fun RoomDetailsView(
onJoinCallClick: () -> Unit,
onPinnedMessagesClick: () -> Unit,
onKnockRequestsClick: () -> Unit,
onSecurityAndPrivacyClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Scaffold(
@@ -185,24 +184,12 @@ fun RoomDetailsView(
}
)
if (state.canShowPinnedMessages) {
PinnedMessagesItem(
pinnedMessagesCount = state.pinnedMessagesCount,
onPinnedMessagesClick = onPinnedMessagesClick
)
}
if (state.displayRolesAndPermissionsSettings) {
ListItem(
headlineContent = { Text(stringResource(R.string.screen_room_details_roles_and_permissions)) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Admin())),
onClick = openAdminSettings,
)
}
SecurityAndPrivacyItem(
onClick = onSecurityAndPrivacyClick
)
}
val displayMemberListItem = state.roomType is RoomDetailsType.Room
if (displayMemberListItem) {
if (state.roomType is RoomDetailsType.Room) {
PreferenceCategory {
MembersItem(
memberCount = state.memberCount,
@@ -214,19 +201,31 @@ fun RoomDetailsView(
onKnockRequestsClick = onKnockRequestsClick
)
}
if (state.displayRolesAndPermissionsSettings) {
ListItem(
headlineContent = { Text(stringResource(R.string.screen_room_details_roles_and_permissions)) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Admin())),
onClick = openAdminSettings,
)
}
}
}
PollsSection(
openPollHistory = openPollHistory
)
if (state.canShowMediaGallery) {
MediaGallerySection(
onClick = openMediaGallery
PreferenceCategory {
if (state.canShowPinnedMessages) {
PinnedMessagesItem(
pinnedMessagesCount = state.pinnedMessagesCount,
onPinnedMessagesClick = onPinnedMessagesClick
)
}
PollsItem(
openPollHistory = openPollHistory
)
}
if (state.isEncrypted) {
SecuritySection()
if (state.canShowMediaGallery) {
MediaGalleryItem(
onClick = openMediaGallery
)
}
}
if (state.roomType is RoomDetailsType.Dm && state.roomMemberDetailsState != null) {
@@ -408,24 +407,26 @@ private fun DmHeaderSection(
}
@Composable
private fun ColumnScope.TitleAndSubtitle(
private fun TitleAndSubtitle(
title: String,
subtitle: String?,
) {
Spacer(modifier = Modifier.height(24.dp))
Text(
text = title,
style = ElementTheme.typography.fontHeadingLgBold,
textAlign = TextAlign.Center,
)
if (subtitle != null) {
Spacer(modifier = Modifier.height(6.dp))
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Spacer(modifier = Modifier.height(24.dp))
Text(
text = subtitle,
style = ElementTheme.typography.fontBodyLgRegular,
color = MaterialTheme.colorScheme.secondary,
text = title,
style = ElementTheme.typography.fontHeadingLgBold,
textAlign = TextAlign.Center,
)
if (subtitle != null) {
Spacer(modifier = Modifier.height(6.dp))
Text(
text = subtitle,
style = ElementTheme.typography.fontBodyLgRegular,
color = MaterialTheme.colorScheme.secondary,
textAlign = TextAlign.Center,
)
}
}
}
@@ -518,6 +519,19 @@ private fun NotificationItem(
)
}
@Composable
private fun SecurityAndPrivacyItem(
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
ListItem(
headlineContent = { Text(stringResource(R.string.screen_room_details_security_and_privacy_title)) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Lock())),
onClick = onClick,
modifier = modifier,
)
}
@Composable
private fun FavoriteItem(
isFavorite: Boolean,
@@ -569,40 +583,25 @@ private fun PinnedMessagesItem(
}
@Composable
private fun PollsSection(
private fun PollsItem(
openPollHistory: () -> Unit,
) {
PreferenceCategory {
ListItem(
headlineContent = { Text(stringResource(R.string.screen_polls_history_title)) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Polls())),
onClick = openPollHistory,
)
}
ListItem(
headlineContent = { Text(stringResource(R.string.screen_polls_history_title)) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Polls())),
onClick = openPollHistory,
)
}
@Composable
private fun MediaGallerySection(
private fun MediaGalleryItem(
onClick: () -> Unit,
) {
PreferenceCategory {
ListItem(
headlineContent = { Text(stringResource(R.string.screen_room_details_media_gallery_title)) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Image())),
onClick = onClick,
)
}
}
@Composable
private fun SecuritySection() {
PreferenceCategory(title = stringResource(R.string.screen_room_details_security_title)) {
ListItem(
headlineContent = { Text(stringResource(R.string.screen_room_details_encryption_enabled_title)) },
supportingContent = { Text(stringResource(R.string.screen_room_details_encryption_enabled_subtitle)) },
leadingContent = ListItemContent.Icon(IconSource.Resource(CommonDrawables.ic_encryption_enabled)),
)
}
ListItem(
headlineContent = { Text(stringResource(R.string.screen_room_details_media_gallery_title)) },
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Image())),
onClick = onClick,
)
}
@Composable
@@ -654,5 +653,6 @@ private fun ContentToPreview(state: RoomDetailsState) {
onJoinCallClick = {},
onPinnedMessagesClick = {},
onKnockRequestsClick = {},
onSecurityAndPrivacyClick = {},
)
}

View File

@@ -17,6 +17,7 @@ import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.isDm
import io.element.android.libraries.matrix.api.room.roomMembers
@Composable
@@ -44,7 +45,7 @@ fun MatrixRoom.getDirectRoomMember(roomMembersState: MatrixRoomMembersState): St
derivedStateOf {
roomMembers
?.filter { it.membership.isActive() }
?.takeIf { it.size == 2 && isDirect }
?.takeIf { isDm }
?.find { it.userId != sessionId }
}
}