diff --git a/features/rolesandpermissions/impl/src/main/res/values/localazy.xml b/features/rolesandpermissions/impl/src/main/res/values/localazy.xml
index 2d98f43f97..77ab04749f 100644
--- a/features/rolesandpermissions/impl/src/main/res/values/localazy.xml
+++ b/features/rolesandpermissions/impl/src/main/res/values/localazy.xml
@@ -35,8 +35,8 @@
"Save changes?"
"There are no banned users."
- - "%1$d person"
- - "%1$d people"
+ - "%1$d Person"
+ - "%1$d People"
"Ban user"
"Only remove member"
@@ -45,7 +45,7 @@
"Unban user"
"Banned"
"Members"
- "Pending"
+ "%1$d Invited"
"Admin"
"Moderator"
"Owner"
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListDataSource.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListDataSource.kt
deleted file mode 100644
index 5e00ce0937..0000000000
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListDataSource.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2025 Element Creations Ltd.
- * Copyright 2023-2025 New Vector Ltd.
- *
- * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
- * Please see LICENSE files in the repository root for full details.
- */
-
-package io.element.android.features.roomdetails.impl.members
-
-import dev.zacsweers.metro.Inject
-import io.element.android.libraries.core.bool.orFalse
-import io.element.android.libraries.core.coroutine.CoroutineDispatchers
-import io.element.android.libraries.matrix.api.room.BaseRoom
-import io.element.android.libraries.matrix.api.room.RoomMember
-import io.element.android.libraries.matrix.api.room.RoomMembershipState
-import io.element.android.libraries.matrix.api.room.roomMembers
-import kotlinx.coroutines.withContext
-import kotlin.collections.filter
-
-@Inject
-class RoomMemberListDataSource(
- private val room: BaseRoom,
- private val coroutineDispatchers: CoroutineDispatchers,
-) {
- suspend fun search(query: String, selectedSection: SelectedSection): List = withContext(coroutineDispatchers.io) {
- val roomMembersState = room.membersStateFlow.value
- val displayableMembers = roomMembersState.roomMembers()
- .orEmpty()
- .filter {
- when(selectedSection){
- SelectedSection.MEMBERS -> it.membership.isActive()
- SelectedSection.BANNED -> it.membership == RoomMembershipState.BAN
- }
- }
-
- val filteredMembers = if (query.isBlank()) {
- displayableMembers
- } else {
- displayableMembers.filter { member ->
- member.userId.value.contains(query, ignoreCase = true) ||
- member.displayName?.contains(query, ignoreCase = true).orFalse()
- }
- }
- filteredMembers
- }
-}
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt
index 9a8798124e..a4b7b22bf3 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt
@@ -13,6 +13,5 @@ import io.element.android.libraries.matrix.api.room.RoomMember
sealed interface RoomMemberListEvents {
data class ChangeSelectedSection(val section: SelectedSection): RoomMemberListEvents
data class UpdateSearchQuery(val query: String) : RoomMemberListEvents
- data class OnSearchActiveChanged(val active: Boolean) : RoomMemberListEvents
data class RoomMemberSelected(val roomMember: RoomMember) : RoomMemberListEvents
}
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt
index 400432d331..44e0aa168f 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt
@@ -23,6 +23,7 @@ import io.element.android.features.roommembermoderation.api.RoomMemberModeration
import io.element.android.features.roommembermoderation.api.RoomMemberModerationState
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.Presenter
+import io.element.android.libraries.architecture.map
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.matrix.api.core.UserId
@@ -41,7 +42,6 @@ import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toImmutableMap
-import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.withContext
@@ -63,8 +63,6 @@ class RoomMemberListPresenter(
var searchResults by remember {
mutableStateOf>>(SearchBarResultState.Initial())
}
- var isSearchActive by rememberSaveable { mutableStateOf(false) }
-
val membersState by room.membersStateFlow.collectAsState()
val syncUpdateFlow = room.syncUpdateFlow.collectAsState()
val canInvite by room.canInviteAsState(syncUpdateFlow.value)
@@ -78,8 +76,9 @@ class RoomMemberListPresenter(
.launchIn(this)
}
- var roomMembers: AsyncData by remember { mutableStateOf(AsyncData.Loading())}
- var selectedSection by remember { mutableStateOf(SelectedSection.MEMBERS)}
+ var roomMembers: AsyncData by remember { mutableStateOf(AsyncData.Loading()) }
+ var selectedSection by remember { mutableStateOf(SelectedSection.MEMBERS) }
+ var filteredRoomMembers: AsyncData by remember { mutableStateOf(AsyncData.Loading()) }
// Update the room members when the screen is loaded
LaunchedEffect(Unit) {
@@ -98,7 +97,7 @@ class RoomMemberListPresenter(
}
withContext(coroutineDispatchers.io) {
val members = membersState.roomMembers().orEmpty().groupBy { it.membership }
- val info = room.roomInfoFlow.first()
+ val info = room.info()
if (members.getOrDefault(RoomMembershipState.JOIN, emptyList()).size < info.joinedMembersCount / 2) {
// Don't display initial room member list if we have less than half of the joined members:
// This result will come from the timeline loading membership events and it'll be wrong.
@@ -125,43 +124,16 @@ class RoomMemberListPresenter(
}
}
- LaunchedEffect(membersState, searchQuery, isSearchActive) {
- withContext(coroutineDispatchers.io) {
- searchResults = if (searchQuery.isEmpty() || !isSearchActive) {
- SearchBarResultState.Initial()
- } else {
- val results = roomMemberListDataSource.search(searchQuery, selectedSection).groupBy { it.membership }
- if (results.isEmpty()) {
- SearchBarResultState.NoResultsFound()
- } else {
- val result = RoomMembers(
- invited = results.getOrDefault(RoomMembershipState.INVITE, emptyList())
- .map { it.withIdentityState(roomMemberIdentityStates) }
- .toImmutableList(),
- joined = results.getOrDefault(RoomMembershipState.JOIN, emptyList())
- .sortedWith(powerLevelRoomMemberComparator)
- .map { it.withIdentityState(roomMemberIdentityStates) }
- .toImmutableList(),
- banned = results.getOrDefault(RoomMembershipState.BAN, emptyList())
- .sortedBy { it.userId.value }
- .map { it.withIdentityState(roomMemberIdentityStates) }
- .toImmutableList(),
- )
- SearchBarResultState.Results(
- if (membersState is RoomMembersState.Pending) {
- AsyncData.Loading(result)
- } else {
- AsyncData.Success(result)
- }
- )
- }
+ LaunchedEffect(searchQuery, roomMembers) {
+ filteredRoomMembers = roomMembers.map { members ->
+ withContext(coroutineDispatchers.io) {
+ members.filter(searchQuery)
}
}
}
fun handleEvent(event: RoomMemberListEvents) {
when (event) {
- is RoomMemberListEvents.OnSearchActiveChanged -> isSearchActive = event.active
is RoomMemberListEvents.UpdateSearchQuery -> searchQuery = event.query
is RoomMemberListEvents.RoomMemberSelected ->
roomModerationState.eventSink(ShowActionsForUser(event.roomMember.toMatrixUser()))
@@ -176,10 +148,8 @@ class RoomMemberListPresenter(
}
return RoomMemberListState(
- roomMembers = roomMembers,
+ roomMembers = filteredRoomMembers,
searchQuery = searchQuery,
- searchResults = searchResults,
- isSearchActive = isSearchActive,
canInvite = canInvite,
moderationState = roomModerationState,
selectedSection = selectedSection,
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt
index 498dfd0180..b59f67a915 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt
@@ -10,16 +10,15 @@ package io.element.android.features.roomdetails.impl.members
import io.element.android.features.roommembermoderation.api.RoomMemberModerationState
import io.element.android.libraries.architecture.AsyncData
-import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
+import io.element.android.libraries.core.bool.orFalse
import io.element.android.libraries.matrix.api.encryption.identity.IdentityState
import io.element.android.libraries.matrix.api.room.RoomMember
import kotlinx.collections.immutable.ImmutableList
+import kotlinx.collections.immutable.toImmutableList
data class RoomMemberListState(
val roomMembers: AsyncData,
val searchQuery: String,
- val searchResults: SearchBarResultState>,
- val isSearchActive: Boolean,
val canInvite: Boolean,
val selectedSection: SelectedSection,
val moderationState: RoomMemberModerationState,
@@ -35,7 +34,22 @@ data class RoomMembers(
val invited: ImmutableList,
val joined: ImmutableList,
val banned: ImmutableList,
-)
+){
+ fun filter(query: String): RoomMembers {
+ if (query.isBlank()) {
+ return this
+ }
+ val filterPredicate = { member: RoomMemberWithIdentityState ->
+ member.roomMember.userId.value.contains(query, ignoreCase = true) ||
+ member.roomMember.displayName?.contains(query, ignoreCase = true).orFalse()
+ }
+ return RoomMembers(
+ invited = invited.filter(filterPredicate).toImmutableList(),
+ joined = joined.filter(filterPredicate).toImmutableList(),
+ banned = banned.filter(filterPredicate).toImmutableList(),
+ )
+ }
+}
data class RoomMemberWithIdentityState(
val roomMember: RoomMember,
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt
index 312efef35c..dafe2546d5 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt
@@ -59,36 +59,21 @@ private fun roomMemberListStates(): Sequence = sequenceOf(
selectedSection = SelectedSection.MEMBERS,
),
aRoomMemberListState().copy(
- isSearchActive = false,
selectedSection = SelectedSection.MEMBERS,
),
aRoomMemberListState().copy(
- isSearchActive = true,
selectedSection = SelectedSection.MEMBERS,
),
aRoomMemberListState().copy(
- isSearchActive = true,
searchQuery = "someone",
selectedSection = SelectedSection.MEMBERS,
),
aRoomMemberListState().copy(
- isSearchActive = true,
searchQuery = "@someone:matrix.org",
- searchResults = SearchBarResultState.Results(
- AsyncData.Success(
- RoomMembers(
- invited = persistentListOf(aVictor().withIdentity()),
- joined = persistentListOf(anAlice().withIdentity()),
- banned = persistentListOf(),
- )
- )
- ),
selectedSection = SelectedSection.MEMBERS,
),
aRoomMemberListState().copy(
- isSearchActive = true,
searchQuery = "something-with-no-results",
- searchResults = SearchBarResultState.NoResultsFound(),
selectedSection = SelectedSection.MEMBERS,
),
aRoomMemberListState(
@@ -143,17 +128,14 @@ private fun bannedRoomMemberListStates(): Sequence = sequen
internal fun aRoomMemberListState(
roomMembers: AsyncData = AsyncData.Loading(),
- searchResults: SearchBarResultState> = SearchBarResultState.Initial(),
moderationState: RoomMemberModerationState = aRoomMemberModerationState(),
selectedSection: SelectedSection = SelectedSection.MEMBERS,
) = RoomMemberListState(
roomMembers = roomMembers,
searchQuery = "",
- searchResults = searchResults,
- isSearchActive = false,
canInvite = false,
moderationState = moderationState,
- selectedSection = SelectedSection.MEMBERS,
+ selectedSection = selectedSection,
eventSink = {}
)
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt
index b2a51aa446..74d3305ff5 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt
@@ -51,8 +51,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.LinearProgressIndicator
import io.element.android.libraries.designsystem.theme.components.Scaffold
-import io.element.android.libraries.designsystem.theme.components.SearchBar
-import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
+import io.element.android.libraries.designsystem.theme.components.SearchField
import io.element.android.libraries.designsystem.theme.components.SegmentedButton
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextButton
@@ -79,44 +78,39 @@ fun RoomMemberListView(
Scaffold(
modifier = modifier,
topBar = {
- if (!state.isSearchActive) {
- RoomMemberListTopBar(
- canInvite = state.canInvite,
- onBackClick = navigator::exitRoomMemberList,
- onInviteClick = navigator::openInviteMembers,
- )
- }
+ RoomMemberListTopBar(
+ canInvite = state.canInvite,
+ onBackClick = navigator::exitRoomMemberList,
+ onInviteClick = navigator::openInviteMembers,
+ )
}
) { padding ->
Column(
modifier = Modifier
- .fillMaxWidth()
- .padding(padding)
- .consumeWindowInsets(padding),
+ .fillMaxWidth()
+ .padding(padding)
+ .consumeWindowInsets(padding),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
- RoomMemberSearchBar(
- query = state.searchQuery,
- state = state.searchResults,
- active = state.isSearchActive,
- placeHolderTitle = stringResource(CommonStrings.common_search_for_someone),
- onActiveChange = { state.eventSink(RoomMemberListEvents.OnSearchActiveChanged(it)) },
- onTextChange = { state.eventSink(RoomMemberListEvents.UpdateSearchQuery(it)) },
- onSelectUser = ::onSelectUser,
- selectedSection = state.selectedSection,
- modifier = Modifier.fillMaxWidth(),
+ var searchQuery by textFieldState(state.searchQuery)
+ SearchField(
+ value = searchQuery,
+ onValueChange = { newQuery ->
+ searchQuery = newQuery
+ state.eventSink(RoomMemberListEvents.UpdateSearchQuery(newQuery))
+ },
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 16.dp),
+ placeholder = stringResource(CommonStrings.common_search_for_someone),
+ )
+ RoomMemberList(
+ roomMembers = state.roomMembers,
+ selectedSection = state.selectedSection,
+ onSelectedSectionChange = { state.eventSink(RoomMemberListEvents.ChangeSelectedSection(it)) },
+ showSections = state.moderationState.canBan,
+ onSelectUser = ::onSelectUser,
)
-
- if (!state.isSearchActive) {
- RoomMemberList(
- roomMembers = state.roomMembers,
- showMembersCount = true,
- canDisplayBannedUsersControls = state.moderationState.canBan,
- selectedSection = state.selectedSection,
- onSelectedSectionChange = { state.eventSink(RoomMemberListEvents.ChangeSelectedSection(it)) },
- onSelectUser = ::onSelectUser,
- )
- }
}
}
}
@@ -124,25 +118,24 @@ fun RoomMemberListView(
@Composable
private fun RoomMemberList(
roomMembers: AsyncData,
- showMembersCount: Boolean,
selectedSection: SelectedSection,
+ showSections: Boolean = true,
onSelectedSectionChange: (SelectedSection) -> Unit,
- canDisplayBannedUsersControls: Boolean,
onSelectUser: (RoomMember) -> Unit,
) {
LazyColumn(modifier = Modifier.fillMaxWidth(), state = rememberLazyListState()) {
stickyHeader {
Column {
- if (canDisplayBannedUsersControls) {
+ if (showSections) {
val segmentedButtonTitles = persistentListOf(
stringResource(id = R.string.screen_room_member_list_mode_members),
stringResource(id = R.string.screen_room_member_list_mode_banned),
)
SingleChoiceSegmentedButtonRow(
modifier = Modifier
- .background(ElementTheme.colors.bgCanvasDefault)
- .fillMaxWidth()
- .padding(start = 16.dp, end = 16.dp, bottom = 16.dp),
+ .background(ElementTheme.colors.bgCanvasDefault)
+ .fillMaxWidth()
+ .padding(start = 16.dp, end = 16.dp, bottom = 16.dp),
) {
for ((index, title) in segmentedButtonTitles.withIndex()) {
SegmentedButton(
@@ -171,7 +164,6 @@ private fun RoomMemberList(
roomMembers = roomMembers.dataOrNull() ?: return@LazyColumn,
selectedSection = selectedSection,
onSelectUser = onSelectUser,
- showMembersCount = showMembersCount,
)
AsyncData.Uninitialized -> Unit
}
@@ -182,27 +174,29 @@ private fun LazyListScope.memberItems(
roomMembers: RoomMembers,
selectedSection: SelectedSection,
onSelectUser: (RoomMember) -> Unit,
- showMembersCount: Boolean,
) {
when (selectedSection) {
SelectedSection.MEMBERS -> {
if (roomMembers.invited.isNotEmpty()) {
- roomMemberListSection(
- headerText = { stringResource(id = R.string.screen_room_member_list_pending_header_title) },
+ roomMemberListSectionHeader(
+ text = {
+ val memberCount = roomMembers.invited.count()
+ stringResource(id = R.string.screen_room_member_list_pending_header_title, memberCount)
+ },
+ )
+ roomMemberListSectionItems(
members = roomMembers.invited,
onMemberSelected = { onSelectUser(it) }
)
}
if (roomMembers.joined.isNotEmpty()) {
- roomMemberListSection(
- headerText = {
- if (showMembersCount) {
- val memberCount = roomMembers.joined.count()
- pluralStringResource(id = R.plurals.screen_room_member_list_header_title, count = memberCount, memberCount)
- } else {
- stringResource(id = R.string.screen_room_member_list_room_members_header_title)
- }
+ roomMemberListSectionHeader(
+ text = {
+ val memberCount = roomMembers.joined.count()
+ pluralStringResource(id = R.plurals.screen_room_member_list_header_title, count = memberCount, memberCount)
},
+ )
+ roomMemberListSectionItems(
members = roomMembers.joined,
onMemberSelected = { onSelectUser(it) }
)
@@ -210,8 +204,14 @@ private fun LazyListScope.memberItems(
}
SelectedSection.BANNED -> { // Banned users
if (roomMembers.banned.isNotEmpty()) {
- roomMemberListSection(
- headerText = null,
+ roomMemberListSectionHeader(
+ text = {
+ val memberCount = roomMembers.banned.count()
+ stringResource(id = R.string.screen_room_member_list_banned_header_title, memberCount)
+ },
+ isCritical = true,
+ )
+ roomMemberListSectionItems(
members = roomMembers.banned,
onMemberSelected = { onSelectUser(it) }
)
@@ -219,13 +219,13 @@ private fun LazyListScope.memberItems(
item {
Box(
Modifier
- .fillParentMaxSize()
- .padding(horizontal = 16.dp)
+ .fillParentMaxSize()
+ .padding(horizontal = 16.dp)
) {
Text(
modifier = Modifier
- .padding(bottom = 56.dp)
- .align(Alignment.Center),
+ .padding(bottom = 56.dp)
+ .align(Alignment.Center),
text = stringResource(id = R.string.screen_room_member_list_banned_empty),
color = ElementTheme.colors.textSecondary,
textAlign = TextAlign.Center,
@@ -241,8 +241,8 @@ private fun LazyListScope.failureItem(failure: Throwable) {
item {
Text(
modifier = Modifier
- .fillMaxWidth()
- .padding(horizontal = 16.dp, vertical = 32.dp),
+ .fillMaxWidth()
+ .padding(horizontal = 16.dp, vertical = 32.dp),
text = stringResource(id = CommonStrings.error_unknown) + "\n\n" + failure.localizedMessage,
color = ElementTheme.colors.textCriticalPrimary,
textAlign = TextAlign.Center,
@@ -250,21 +250,25 @@ private fun LazyListScope.failureItem(failure: Throwable) {
}
}
-private fun LazyListScope.roomMemberListSection(
- headerText: @Composable (() -> String)?,
+private fun LazyListScope.roomMemberListSectionHeader(
+ text: @Composable (() -> String),
+ modifier: Modifier = Modifier,
+ isCritical: Boolean = false,
+) {
+ item {
+ Text(
+ modifier = modifier.padding(horizontal = 16.dp, vertical = 12.dp),
+ text = text(),
+ style = ElementTheme.typography.fontBodyLgMedium,
+ color = if (isCritical) ElementTheme.colors.textCriticalPrimary else ElementTheme.colors.textPrimary,
+ )
+ }
+}
+
+private fun LazyListScope.roomMemberListSectionItems(
members: ImmutableList?,
onMemberSelected: (RoomMember) -> Unit,
) {
- headerText?.let {
- item {
- Text(
- modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp),
- text = it(),
- style = ElementTheme.typography.fontBodyLgRegular,
- color = ElementTheme.colors.textSecondary,
- )
- }
- }
items(members.orEmpty()) { matrixUser ->
RoomMemberListItem(
modifier = Modifier.fillMaxWidth(),
@@ -353,44 +357,6 @@ private fun RoomMemberListTopBar(
)
}
-@OptIn(ExperimentalMaterial3Api::class)
-@Composable
-private fun RoomMemberSearchBar(
- query: String,
- state: SearchBarResultState>,
- active: Boolean,
- placeHolderTitle: String,
- onActiveChange: (Boolean) -> Unit,
- onTextChange: (String) -> Unit,
- onSelectUser: (RoomMember) -> Unit,
- selectedSection: SelectedSection,
- modifier: Modifier = Modifier,
-) {
- var queryFieldState by textFieldState(query)
- SearchBar(
- query = queryFieldState,
- onQueryChange = { newQuery ->
- queryFieldState = newQuery
- onTextChange(newQuery)
- },
- active = active,
- onActiveChange = onActiveChange,
- modifier = modifier,
- placeHolderTitle = placeHolderTitle,
- resultState = state,
- resultHandler = { results ->
- RoomMemberList(
- roomMembers = results,
- showMembersCount = false,
- onSelectUser = { onSelectUser(it) },
- canDisplayBannedUsersControls = false,
- selectedSection = selectedSection,
- onSelectedSectionChange = {},
- )
- },
- )
-}
-
@PreviewsDayNight
@Composable
internal fun RoomMemberListViewPreview(@PreviewParameter(RoomMemberListStateProvider::class) state: RoomMemberListState) = ElementPreview {
diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml
index 2f9f2de9b7..4d8e634e81 100644
--- a/features/roomdetails/impl/src/main/res/values/localazy.xml
+++ b/features/roomdetails/impl/src/main/res/values/localazy.xml
@@ -71,9 +71,10 @@
"Topic"
"Updating room…"
"There are no banned users."
+ "%1$d Banned"
- - "%1$d person"
- - "%1$d people"
+ - "%1$d Person"
+ - "%1$d People"
"Ban user"
"Only remove member"
@@ -82,7 +83,8 @@
"Unban user"
"Banned"
"Members"
- "Pending"
+ "%1$d Invited"
+ "Pending"
"Admin"
"Moderator"
"Owner"
diff --git a/tools/localazy/config.json b/tools/localazy/config.json
index 405451bb34..27ca1ecd12 100644
--- a/tools/localazy/config.json
+++ b/tools/localazy/config.json
@@ -198,6 +198,7 @@
"screen_room_details_.*",
"screen\\.room_details\\..*",
"screen_room_member_list_.*",
+ "screen\\.room_member_list\\..*",
"screen_room_notification_settings_.*",
"screen_notification_settings_edit_failed_updating_default_mode",
"screen_polls_history_title",