Repository: element-hq/element-x-android (language: kotlin)

Issue:
Categorise members by role in the `ChangeRoles` screen
In Settings -> Roles and permissions -> Admins or Moderators we want to have a clearer distinction for which members have which roles.

Changes needed:

- Add different sections for the 3 main roles: Admins, Moderators, Members, in that order, and display the users in each category.
- For users whose role can't be changed display a disabled checkbox instead of an empty space in the right of the list item.
- If the user is in a pending state (invited, not joined yet) display a 'Pending' label next to their display name and before the checkbox. Designs are pending for this at the moment.

See the parent issue for more details on this.


Discussion hints:
nan

Pull request: Categorise members by role in the ChangeRoles screen
<!-- Please read [CONTRIBUTING.md](https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md) before submitting your pull request -->
 
## Type of change

- [ ] Feature
- [ ] Bugfix
- [ ] Technical
- [x] Other : UI change.

## Content

- Categorises members in different sections by role in the change roles screens.
- For the change role to moderator screen, also add a subtitle notice confirming administrators already have moderator permissions.
- For users who have been invited to the room, add a 'Pending' label next to their names.
- Automatically reload member list when power levels or membership of members change.
- Replace empty space next to users whose level can't be changed to disabled checkboxes to match [the latest Figma designs](https://www.figma.com/file/A2pAEvTEpJZBiOPUlcMnKi/Settings-%2B-Room-Details-(new)?type=design&node-id=1739-17431&mode=design&t=jsOy8TlfwaXCU1dR-4).

## Motivation and context

Fixes #2593 .

## Screenshots / GIFs

|Before|After|
|-|-|
|![](https://media.githubusercontent.com/media/element-hq/element-x-android/103743c33812a7cd4dae14f7104ad0a234f48c52/tests/uitests/src/test/snapshots/images/ui_S_t%5Bf.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_3%2CNEXUS_5%2C1.0%2Cen%5D.png)|![](https://media.githubusercontent.com/media/element-hq/element-x-android/c6ea6d2327a0532fdb74ba30d474217390fea526/tests/uitests/src/test/snapshots/images/ui_S_t%5Bf.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_3%2CNEXUS_5%2C1.0%2Cen%5D.png)|

## Tests

<!-- Explain how you tested your development -->

- Go into a room where you're an admin.
- Open its settings -> roles and permissions -> roles (admins or moderators).
- Verify the new design is used and the feature works.

## Tested devices

- [x] Physical
- [ ] Emulator
- OS version(s): 14

## Checklist

<!-- Depending on the Pull Request content, it can be acceptable if some of the following checkboxes stay unchecked. -->

- [ ] Changes have been tested on an Android device or Android emulator with API 23
- [x] UI change has been tested on both light and dark themes
- [ ] Accessibility has been taken into account. See https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md#accessibility
- [x] Pull request is based on the develop branch
- [x] Pull request includes a new file under ./changelog.d. See https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md#changelog
- [x] Pull request includes screenshots or videos if containing UI changes
- [ ] Pull request includes a [sign off](https://matrix-org.github.io/synapse/latest/development/contributing_guide.html#sign-off)
- [x] You've made a self review of your PR


Test command: ./gradlew :features:roomdetails:impl:testDebugUnitTest --tests "io.element.android.features.roomdetails.rolesandpermissions.changeroles.ChangeRolesViewTest" --tests "io.element.android.features.roomdetails.rolesandpermissions.changeroles.ChangeRolesPresenterTests" --tests "io.element.android.features.roomdetails.rolesandpermissions.changeroles.MembersByRoleTest"

Fix patch:
diff --git a/changelog.d/2593.misc b/changelog.d/2593.misc
new file mode 100644
index 00000000000..e67bfc68e57
--- /dev/null
+++ b/changelog.d/2593.misc
@@ -0,0 +1,1 @@
+Categorise members by role in change roles screen.
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesNode.kt
index 291beebe996..acd0d7c20c7 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesNode.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesNode.kt
@@ -65,7 +65,7 @@ class ChangeRolesNode @AssistedInject constructor(
         ChangeRolesView(
             modifier = modifier,
             state = state,
-            onBackPressed = this::navigateUp,
+            navigateUp = this::navigateUp,
         )
     }
 }
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesPresenter.kt
index 403b3f3e5dd..b4522367ec4 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesPresenter.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesPresenter.kt
@@ -75,7 +75,7 @@ class ChangeRolesPresenter @AssistedInject constructor(
         var query by rememberSaveable { mutableStateOf<String?>(null) }
         var searchActive by rememberSaveable { mutableStateOf(false) }
         var searchResults by remember {
-            mutableStateOf<SearchBarResultState<ImmutableList<RoomMember>>>(SearchBarResultState.Initial())
+            mutableStateOf<SearchBarResultState<MembersByRole>>(SearchBarResultState.Initial())
         }
         val selectedUsers = remember {
             mutableStateOf<ImmutableList<MatrixUser>>(persistentListOf())
@@ -91,7 +91,7 @@ class ChangeRolesPresenter @AssistedInject constructor(
                     // Users who were selected but didn't have the role, so their role change was pending
                     val toAdd = selectedUsers.value.filter { user -> users.none { it.userId == user.userId } && previous.none { it.userId == user.userId } }
                     // Users who no longer have the role
-                    val toRemove = previous.filter { user -> users.none { it.userId == user.userId } }
+                    val toRemove = previous.filter { user -> users.none { it.userId == user.userId } }.toSet()
                     selectedUsers.value = (users + toAdd - toRemove).toImmutableList()
                 }
                 .launchIn(this)
@@ -103,8 +103,9 @@ class ChangeRolesPresenter @AssistedInject constructor(
         LaunchedEffect(query, roomMemberState) {
             val results = dataSource
                 .search(query.orEmpty())
-                .sorted()
+                .groupedByRole()
 
+            println(results)
             searchResults = if (results.isEmpty()) {
                 SearchBarResultState.NoResultsFound()
             } else {
@@ -181,6 +182,14 @@ class ChangeRolesPresenter @AssistedInject constructor(
         )
     }
 
+    private fun List<RoomMember>.groupedByRole(): MembersByRole {
+        return MembersByRole(
+            admins = filter { it.role == RoomMember.Role.ADMIN }.sorted(),
+            moderators = filter { it.role == RoomMember.Role.MODERATOR }.sorted(),
+            members = filter { it.role == RoomMember.Role.USER }.sorted(),
+        )
+    }
+
     private fun Iterable<RoomMember>.sorted(): ImmutableList<RoomMember> {
         return sortedWith(PowerLevelRoomMemberComparator()).toImmutableList()
     }
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesState.kt
index 79a955df13e..973363ae6a0 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesState.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesState.kt
@@ -16,18 +16,20 @@
 
 package io.element.android.features.roomdetails.impl.rolesandpermissions.changeroles
 
+import io.element.android.features.roomdetails.impl.members.PowerLevelRoomMemberComparator
 import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
 import io.element.android.libraries.matrix.api.core.UserId
 import io.element.android.libraries.matrix.api.room.RoomMember
 import io.element.android.libraries.matrix.api.user.MatrixUser
 import kotlinx.collections.immutable.ImmutableList
+import kotlinx.collections.immutable.toImmutableList
 
 data class ChangeRolesState(
     val role: RoomMember.Role,
     val query: String?,
     val isSearchActive: Boolean,
-    val searchResults: SearchBarResultState<ImmutableList<RoomMember>>,
+    val searchResults: SearchBarResultState<MembersByRole>,
     val selectedUsers: ImmutableList<MatrixUser>,
     val hasPendingChanges: Boolean,
     val exitState: AsyncAction<Unit>,
@@ -35,3 +37,21 @@ data class ChangeRolesState(
     val canChangeMemberRole: (UserId) -> Boolean,
     val eventSink: (ChangeRolesEvent) -> Unit,
 )
+
+data class MembersByRole(
+    val admins: ImmutableList<RoomMember>,
+    val moderators: ImmutableList<RoomMember>,
+    val members: ImmutableList<RoomMember>,
+) {
+    constructor(members: List<RoomMember>) : this(
+            admins = members.filter { it.role == RoomMember.Role.ADMIN }.sorted(),
+            moderators = members.filter { it.role == RoomMember.Role.MODERATOR }.sorted(),
+            members = members.filter { it.role == RoomMember.Role.USER }.sorted(),
+    )
+
+    fun isEmpty() = admins.isEmpty() && moderators.isEmpty() && members.isEmpty()
+}
+
+private fun Iterable<RoomMember>.sorted(): ImmutableList<RoomMember> {
+    return sortedWith(PowerLevelRoomMemberComparator()).toImmutableList()
+}
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesStateProvider.kt
index 8cd5db01d6f..c0e1a2c1350 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesStateProvider.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesStateProvider.kt
@@ -22,6 +22,7 @@ import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
 import io.element.android.libraries.matrix.api.core.UserId
 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.user.MatrixUser
 import io.element.android.libraries.matrix.ui.components.aMatrixUserList
 import kotlinx.collections.immutable.ImmutableList
@@ -32,7 +33,7 @@ class ChangeRolesStateProvider : PreviewParameterProvider<ChangeRolesState> {
     override val values: Sequence<ChangeRolesState>
         get() = sequenceOf(
             aChangeRolesState(),
-            aChangeRolesState(role = RoomMember.Role.MODERATOR),
+            aChangeRolesStateWithSelectedUsers().copy(role = RoomMember.Role.MODERATOR),
             aChangeRolesStateWithSelectedUsers().copy(hasPendingChanges = false),
             aChangeRolesStateWithSelectedUsers(),
             aChangeRolesStateWithSelectedUsers().copy(
@@ -41,7 +42,7 @@ class ChangeRolesStateProvider : PreviewParameterProvider<ChangeRolesState> {
             aChangeRolesStateWithSelectedUsers().copy(
                 query = "Alice",
                 isSearchActive = true,
-                searchResults = SearchBarResultState.Results(aRoomMemberList().take(1).toImmutableList()),
+                searchResults = SearchBarResultState.Results(MembersByRole(aRoomMemberList().take(1).toImmutableList())),
                 selectedUsers = aMatrixUserList().take(1).toImmutableList(),
             ),
             aChangeRolesStateWithSelectedUsers().copy(exitState = AsyncAction.Confirming),
@@ -56,7 +57,7 @@ internal fun aChangeRolesState(
     role: RoomMember.Role = RoomMember.Role.ADMIN,
     query: String? = null,
     isSearchActive: Boolean = false,
-    searchResults: SearchBarResultState<ImmutableList<RoomMember>> = SearchBarResultState.NoResultsFound(),
+    searchResults: SearchBarResultState<MembersByRole> = SearchBarResultState.NoResultsFound(),
     selectedUsers: ImmutableList<MatrixUser> = persistentListOf(),
     hasPendingChanges: Boolean = false,
     exitState: AsyncAction<Unit> = AsyncAction.Uninitialized,
@@ -78,7 +79,17 @@ internal fun aChangeRolesState(
 
 internal fun aChangeRolesStateWithSelectedUsers() = aChangeRolesState(
     selectedUsers = aMatrixUserList().toImmutableList(),
-    searchResults = SearchBarResultState.Results(aRoomMemberList().toImmutableList()),
+    searchResults = SearchBarResultState.Results(
+        MembersByRole(
+            members = aRoomMemberList().mapIndexed { index, roomMember ->
+                if (index % 2 == 0) {
+                    roomMember.copy(membership = RoomMembershipState.INVITE)
+                } else {
+                    roomMember
+                }
+            }
+        )
+    ),
     hasPendingChanges = true,
     canRemoveMember = { it != UserId("@alice:server.org") },
 )
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesView.kt
index f24ee3b0f17..a498456aec7 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesView.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/rolesandpermissions/changeroles/ChangeRolesView.kt
@@ -26,8 +26,10 @@ import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.heightIn
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.statusBarsPadding
 import androidx.compose.foundation.layout.systemBarsPadding
@@ -36,12 +38,16 @@ import androidx.compose.foundation.lazy.LazyListState
 import androidx.compose.foundation.lazy.items
 import androidx.compose.foundation.lazy.rememberLazyListState
 import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.font.FontStyle
+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
@@ -52,6 +58,9 @@ import io.element.android.libraries.designsystem.components.async.AsyncActionVie
 import io.element.android.libraries.designsystem.components.async.AsyncIndicator
 import io.element.android.libraries.designsystem.components.async.AsyncIndicatorHost
 import io.element.android.libraries.designsystem.components.async.rememberAsyncIndicatorState
+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
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
 import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
@@ -67,22 +76,22 @@ import io.element.android.libraries.designsystem.theme.components.TextButton
 import io.element.android.libraries.designsystem.theme.components.TopAppBar
 import io.element.android.libraries.matrix.api.core.UserId
 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.getBestName
 import io.element.android.libraries.matrix.api.room.toMatrixUser
 import io.element.android.libraries.matrix.api.user.MatrixUser
-import io.element.android.libraries.matrix.ui.components.MatrixUserRow
 import io.element.android.libraries.matrix.ui.components.SelectedUsersRowList
 import io.element.android.libraries.ui.strings.CommonStrings
 import kotlinx.collections.immutable.ImmutableList
-import kotlinx.collections.immutable.persistentListOf
 
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun ChangeRolesView(
     state: ChangeRolesState,
-    onBackPressed: () -> Unit,
+    navigateUp: () -> Unit,
     modifier: Modifier = Modifier,
 ) {
-    val updatedOnBackPressed by rememberUpdatedState(newValue = onBackPressed)
+    val updatedNavigateUp by rememberUpdatedState(newValue = navigateUp)
     BackHandler(enabled = !state.isSearchActive) {
         state.eventSink(ChangeRolesEvent.Exit)
     }
@@ -136,7 +145,7 @@ fun ChangeRolesView(
                     resultState = state.searchResults,
                 ) { members ->
                     SearchResultsList(
-                        isSearchActive = true,
+                        currentRole = state.role,
                         lazyListState = lazyListState,
                         searchResults = members,
                         selectedUsers = state.selectedUsers,
@@ -152,9 +161,9 @@ fun ChangeRolesView(
                 ) {
                     Column {
                         SearchResultsList(
-                            isSearchActive = false,
+                            currentRole = state.role,
                             lazyListState = lazyListState,
-                            searchResults = (state.searchResults as? SearchBarResultState.Results)?.results ?: persistentListOf(),
+                            searchResults = (state.searchResults as? SearchBarResultState.Results)?.results ?: MembersByRole(emptyList()),
                             selectedUsers = state.selectedUsers,
                             canRemoveMember = state.canChangeMemberRole,
                             onSelectionToggled = { state.eventSink(ChangeRolesEvent.UserSelectionToggled(it.toMatrixUser())) },
@@ -179,7 +188,7 @@ fun ChangeRolesView(
 
         AsyncActionView(
             async = state.exitState,
-            onSuccess = { updatedOnBackPressed() },
+            onSuccess = { updatedNavigateUp() },
             confirmationDialog = {
                 ConfirmationDialog(
                     title = stringResource(CommonStrings.dialog_unsaved_changes_title),
@@ -227,8 +236,8 @@ fun ChangeRolesView(
 @OptIn(ExperimentalFoundationApi::class)
 @Composable
 private fun SearchResultsList(
-    isSearchActive: Boolean,
-    searchResults: ImmutableList<RoomMember>,
+    currentRole: RoomMember.Role,
+    searchResults: MembersByRole,
     selectedUsers: ImmutableList<MatrixUser>,
     canRemoveMember: (UserId) -> Boolean,
     onSelectionToggled: (RoomMember) -> Unit,
@@ -241,43 +250,145 @@ private fun SearchResultsList(
         item {
             selectedUsersList(selectedUsers)
         }
-        stickyHeader {
-            val textResId = if (isSearchActive) {
-                CommonStrings.common_search_results
-            } else {
-                R.string.screen_room_member_list_room_members_header_title
+        if (searchResults.admins.isNotEmpty()) {
+            stickyHeader { ListSectionHeader(text = stringResource(R.string.screen_room_roles_and_permissions_admins)) }
+            // Add a footer for the admin section in change role to moderator screen
+            if (currentRole == RoomMember.Role.MODERATOR) {
+                item {
+                    Text(
+                        modifier = Modifier
+                            .padding(start = 16.dp, end = 16.dp, bottom = 8.dp),
+                        text = stringResource(R.string.screen_room_change_role_moderators_admin_section_footer),
+                        color = ElementTheme.colors.textSecondary,
+                        style = ElementTheme.typography.fontBodySmRegular,
+                    )
+                }
+            }
+            items(searchResults.admins, key = { it.userId }) { roomMember ->
+                ListMemberItem(
+                    roomMember = roomMember,
+                    canRemoveMember = canRemoveMember,
+                    onSelectionToggled = onSelectionToggled,
+                    selectedUsers = selectedUsers
+                )
             }
-            Text(
-                modifier = Modifier
-                    .background(ElementTheme.colors.bgCanvasDefault)
-                    .padding(horizontal = 16.dp, vertical = 8.dp)
-                    .fillMaxWidth(),
-                text = stringResource(textResId),
-                style = ElementTheme.typography.fontBodyLgMedium,
-            )
         }
-        items(searchResults, key = { it.userId }) { roomMember ->
-            val canToggle = canRemoveMember(roomMember.userId)
-            val trailingContent: @Composable (() -> Unit)? = if (canToggle) {
-                {
-                    Checkbox(
-                        checked = selectedUsers.any { it.userId == roomMember.userId },
-                        onCheckedChange = { onSelectionToggled(roomMember) },
+        if (searchResults.moderators.isNotEmpty()) {
+            stickyHeader { ListSectionHeader(text = stringResource(R.string.screen_room_roles_and_permissions_moderators)) }
+            items(searchResults.moderators, key = { it.userId }) { roomMember ->
+                ListMemberItem(
+                    roomMember = roomMember,
+                    canRemoveMember = canRemoveMember,
+                    onSelectionToggled = onSelectionToggled,
+                    selectedUsers = selectedUsers
+                )
+            }
+        }
+        if (searchResults.admins.isNotEmpty()) {
+            stickyHeader { ListSectionHeader(text = stringResource(R.string.screen_room_member_list_mode_members)) }
+            items(searchResults.members, key = { it.userId }) { roomMember ->
+                ListMemberItem(
+                    roomMember = roomMember,
+                    canRemoveMember = canRemoveMember,
+                    onSelectionToggled = onSelectionToggled,
+                    selectedUsers = selectedUsers
+                )
+            }
+        }
+    }
+}
+
+@Composable
+private fun ListSectionHeader(text: String) {
+    Text(
+        modifier = Modifier
+            .background(ElementTheme.colors.bgCanvasDefault)
+            .padding(horizontal = 16.dp, vertical = 8.dp)
+            .fillMaxWidth(),
+        text = text,
+        style = ElementTheme.typography.fontBodyLgMedium,
+    )
+}
+
+@Composable
+private fun ListMemberItem(
+    roomMember: RoomMember,
+    canRemoveMember: (UserId) -> Boolean,
+    onSelectionToggled: (RoomMember) -> Unit,
+    selectedUsers: ImmutableList<MatrixUser>,
+) {
+    val canToggle = canRemoveMember(roomMember.userId)
+    val trailingContent: @Composable (() -> Unit) = {
+        Checkbox(
+            checked = selectedUsers.any { it.userId == roomMember.userId },
+            onCheckedChange = { onSelectionToggled(roomMember) },
+            enabled = canToggle,
+        )
+    }
+    MemberRow(
+        modifier = Modifier.clickable(enabled = canToggle, onClick = { onSelectionToggled(roomMember) }),
+        avatarData = AvatarData(roomMember.userId.value, roomMember.displayName, roomMember.avatarUrl, AvatarSize.UserListItem),
+        name = roomMember.getBestName(),
+        userId = roomMember.userId.value.takeIf { roomMember.displayName?.isNotBlank() == true },
+        isPending = roomMember.membership == RoomMembershipState.INVITE,
+        trailingContent = trailingContent,
+    )
+}
+
+@Composable
+private fun MemberRow(
+    avatarData: AvatarData,
+    name: String,
+    userId: String?,
+    isPending: Boolean,
+    modifier: Modifier = Modifier,
+    trailingContent: @Composable (() -> Unit)? = null,
+) {
+    Row(
+        modifier = modifier
+            .fillMaxWidth()
+            .heightIn(min = 56.dp)
+            .padding(start = 16.dp, top = 4.dp, end = 16.dp, bottom = 4.dp),
+        verticalAlignment = Alignment.CenterVertically
+    ) {
+        Avatar(avatarData)
+        Column(
+            modifier = Modifier
+                .padding(start = 12.dp)
+                .weight(1f),
+        ) {
+            Row(verticalAlignment = Alignment.CenterVertically) {
+                // Name
+                Text(
+                    modifier = Modifier.weight(1f, fill = false),
+                    text = name,
+                    maxLines = 1,
+                    overflow = TextOverflow.Ellipsis,
+                    color = MaterialTheme.colorScheme.primary,
+                    style = ElementTheme.typography.fontBodyLgRegular,
+                )
+                // Invitation pending marker
+                if (isPending) {
+                    Text(
+                        modifier = Modifier.padding(start = 8.dp),
+                        text = stringResource(id = R.string.screen_room_member_list_pending_header_title),
+                        style = ElementTheme.typography.fontBodySmRegular.copy(fontStyle = FontStyle.Italic),
+                        color = MaterialTheme.colorScheme.secondary
                     )
                 }
-            } else {
-                null
             }
-            MatrixUserRow(
-                modifier = Modifier.clickable(enabled = canToggle, onClick = { onSelectionToggled(roomMember) }),
-                matrixUser = MatrixUser(
-                    userId = roomMember.userId,
-                    displayName = roomMember.displayName,
-                    avatarUrl = roomMember.avatarUrl,
-                ),
-                trailingContent = trailingContent,
-            )
+            // Id
+            userId?.let {
+                Text(
+                    text = userId,
+                    color = MaterialTheme.colorScheme.secondary,
+                    maxLines = 1,
+                    overflow = TextOverflow.Ellipsis,
+                    style = ElementTheme.typography.fontBodySmRegular,
+                )
+            }
         }
+        trailingContent?.invoke()
     }
 }
 
@@ -287,7 +398,27 @@ internal fun ChangeRolesViewPreview(@PreviewParameter(ChangeRolesStateProvider::
     ElementPreview {
         ChangeRolesView(
             state = state,
-            onBackPressed = {},
+            navigateUp = {},
+        )
+    }
+}
+
+@PreviewsDayNight
+@Composable
+internal fun PendingMemberRowWithLongNamePreview() {
+    ElementPreview {
+        MemberRow(
+            avatarData = AvatarData("userId", "A very long name that should be truncated", "https://example.com/avatar.png", AvatarSize.UserListItem),
+            name = "A very long name that should be truncated",
+            userId = "@alice:matrix.org",
+            isPending = true,
+            trailingContent = {
+                Checkbox(
+                    checked = true,
+                    onCheckedChange = {},
+                    enabled = true,
+                )
+            }
         )
     }
 }
diff --git a/features/roomlist/impl/src/main/res/values-de/translations.xml b/features/roomlist/impl/src/main/res/values-de/translations.xml
index a2cf494b1b1..d02870ccd14 100644
--- a/features/roomlist/impl/src/main/res/values-de/translations.xml
+++ b/features/roomlist/impl/src/main/res/values-de/translations.xml
@@ -11,6 +11,8 @@
   <string name="screen_roomlist_filter_favourites_empty_state_subtitle">"In den Chat-Einstellungen kannst du einen Chat als Favorit hinzufügen.
 Um deine anderen Chats zu sehen wähle diesen Filter ab."</string>
   <string name="screen_roomlist_filter_favourites_empty_state_title">"Du hast noch keine Chats als Favorit markiert."</string>
+  <string name="screen_roomlist_filter_invites">"Einladungen"</string>
+  <string name="screen_roomlist_filter_invites_empty_state_title">"Du hast keine ausstehenden Einladungen."</string>
   <string name="screen_roomlist_filter_low_priority">"Niedrige Priorität"</string>
   <string name="screen_roomlist_filter_mixed_empty_state_subtitle">"Wähle Filter ab, um Deine Chats zu sehen."</string>
   <string name="screen_roomlist_filter_mixed_empty_state_title">"Du hast keine Chats für diese Auswahl"</string>
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/setup/views/RecoveryKeyView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/setup/views/RecoveryKeyView.kt
index 7a4d92fcd32..dc8b788025f 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/setup/views/RecoveryKeyView.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/setup/views/RecoveryKeyView.kt
@@ -70,7 +70,10 @@ internal fun RecoveryKeyView(
         verticalArrangement = Arrangement.spacedBy(8.dp)
     ) {
         Text(
-            text = stringResource(id = CommonStrings.common_recovery_key),
+            text = when (state.recoveryKeyUserStory) {
+                RecoveryKeyUserStory.Enter -> stringResource(R.string.screen_recovery_key_confirm_key_label)
+                else -> stringResource(id = CommonStrings.common_recovery_key)
+            },
             modifier = Modifier.padding(start = 16.dp),
             style = ElementTheme.typography.fontBodyMdRegular,
         )
diff --git a/features/securebackup/impl/src/main/res/values-de/translations.xml b/features/securebackup/impl/src/main/res/values-de/translations.xml
index afb1c764d18..f2ac7c06b47 100644
--- a/features/securebackup/impl/src/main/res/values-de/translations.xml
+++ b/features/securebackup/impl/src/main/res/values-de/translations.xml
@@ -30,6 +30,10 @@
   <string name="screen_recovery_key_confirm_error_content">"Bitte versuche es noch einmal, um den Zugriff auf dein Chat-Backup zu bestätigen."</string>
   <string name="screen_recovery_key_confirm_error_title">"Falscher Wiederherstellungsschlüssel"</string>
   <string name="screen_recovery_key_confirm_key_description">"Dies funktioniert auch mit einer Wiederherstellungspassphrase oder einer geheime Passphrase/einem geheimen Schlüssel."</string>
+  <string name="screen_recovery_key_confirm_key_label">
+    <b>"Wiederherstellungsschlüssel"</b>
+    " oder Passcode"
+  </string>
   <string name="screen_recovery_key_confirm_key_placeholder">"Eingeben…"</string>
   <string name="screen_recovery_key_confirm_success">"Wiederherstellungsschlüssel bestätigt"</string>
   <string name="screen_recovery_key_confirm_title">"Wiederherstellungsschlüssel oder Passcode bestätigen"</string>
diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt
index be61b063103..91e25d2498c 100644
--- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt
+++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt
@@ -71,8 +71,13 @@ import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.drop
 import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 import org.matrix.rustcomponents.sdk.EventTimelineItem
@@ -164,7 +169,11 @@ class RustMatrixRoom(
     override val syncUpdateFlow: StateFlow<Long> = _syncUpdateFlow.asStateFlow()
 
     init {
-        timeline.membershipChangeEventReceived
+        val powerLevelChanges = roomInfoFlow.map { it.userPowerLevels }.distinctUntilChanged()
+        val membershipChanges = timeline.membershipChangeEventReceived.onStart { emit(Unit) }
+        combine(membershipChanges, powerLevelChanges) { _, _ -> }
+            // Skip initial one
+            .drop(1)
             // The new events should already be in the SDK cache, no need to fetch them from the server
             .onEach { roomMemberListFetcher.fetchRoomMembers(source = RoomMemberListFetcher.Source.CACHE) }
             .launchIn(roomCoroutineScope)
diff --git a/libraries/ui-strings/src/main/res/values-de/translations.xml b/libraries/ui-strings/src/main/res/values-de/translations.xml
index 719dcab0932..8277b617319 100644
--- a/libraries/ui-strings/src/main/res/values-de/translations.xml
+++ b/libraries/ui-strings/src/main/res/values-de/translations.xml
@@ -175,7 +175,9 @@
   <string name="common_privacy_policy">"Datenschutz­erklärung"</string>
   <string name="common_reaction">"Reaktion"</string>
   <string name="common_reactions">"Reaktionen"</string>
-  <string name="common_recovery_key">"Wiederherstellungsschlüssel oder Passcode"</string>
+  <string name="common_recovery_key">
+    <b>"Wiederherstellungsschlüssel"</b>
+  </string>
   <string name="common_refreshing">"Wird erneuert…"</string>
   <string name="common_replying_to">"%1$s antworten"</string>
   <string name="common_report_a_bug">"Einen Fehler melden"</string>


Test patch:
diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/rolesandpermissions/changeroles/ChangeRolesPresenterTests.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/rolesandpermissions/changeroles/ChangeRolesPresenterTests.kt
index 1dbce1fc53d..e8ff232222b 100644
--- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/rolesandpermissions/changeroles/ChangeRolesPresenterTests.kt
+++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/rolesandpermissions/changeroles/ChangeRolesPresenterTests.kt
@@ -106,15 +106,19 @@ class ChangeRolesPresenterTests {
             presenter.present()
         }.test {
             val initialState = awaitItem()
-            val initialResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results.orEmpty()
-            assertThat(initialResults).hasSize(10)
+            val initialResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results
+            assertThat(initialResults?.members).hasSize(8)
+            assertThat(initialResults?.moderators).hasSize(1)
+            assertThat(initialResults?.admins).hasSize(1)
 
             initialState.eventSink(ChangeRolesEvent.QueryChanged("Alice"))
             skipItems(1)
 
-            val searchResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results.orEmpty()
-            assertThat(searchResults).hasSize(1)
-            assertThat(searchResults.firstOrNull()?.userId).isEqualTo(A_USER_ID)
+            val searchResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results
+            assertThat(searchResults?.admins).hasSize(1)
+            assertThat(searchResults?.moderators).isEmpty()
+            assertThat(searchResults?.members).isEmpty()
+            assertThat(searchResults?.admins?.firstOrNull()?.userId).isEqualTo(A_USER_ID)
         }
     }
 
@@ -128,15 +132,19 @@ class ChangeRolesPresenterTests {
             presenter.present()
         }.test {
             skipItems(1)
-            val initialResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results.orEmpty()
-            assertThat(initialResults).hasSize(10)
+            val initialResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results
+            assertThat(initialResults?.members).hasSize(8)
+            assertThat(initialResults?.moderators).hasSize(1)
+            assertThat(initialResults?.admins).hasSize(1)
 
             room.givenRoomMembersState(MatrixRoomMembersState.Ready(aRoomMemberList().take(1).toPersistentList()))
             skipItems(1)
 
-            val searchResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results.orEmpty()
-            assertThat(searchResults).hasSize(1)
-            assertThat(searchResults.firstOrNull()?.userId).isEqualTo(A_USER_ID)
+            val searchResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results
+            assertThat(searchResults?.admins).hasSize(1)
+            assertThat(searchResults?.moderators).isEmpty()
+            assertThat(searchResults?.members).isEmpty()
+            assertThat(searchResults?.admins?.firstOrNull()?.userId).isEqualTo(A_USER_ID)
         }
     }
 
diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/rolesandpermissions/changeroles/ChangeRolesViewTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/rolesandpermissions/changeroles/ChangeRolesViewTest.kt
index 037223327ef..93cbad4d584 100644
--- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/rolesandpermissions/changeroles/ChangeRolesViewTest.kt
+++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/rolesandpermissions/changeroles/ChangeRolesViewTest.kt
@@ -37,178 +37,192 @@ import io.element.android.libraries.matrix.api.room.toMatrixUser
 import io.element.android.libraries.matrix.ui.components.aMatrixUserList
 import io.element.android.libraries.ui.strings.CommonStrings
 import io.element.android.tests.testutils.EnsureNeverCalled
+import io.element.android.tests.testutils.EnsureNeverCalledWithParam
 import io.element.android.tests.testutils.EventsRecorder
 import io.element.android.tests.testutils.clickOn
 import io.element.android.tests.testutils.pressBack
+import io.element.android.tests.testutils.pressBackKey
 import kotlinx.collections.immutable.toImmutableList
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.TestRule
 import org.junit.runner.RunWith
+import org.robolectric.annotation.Config
+import java.lang.IllegalStateException
 
 @RunWith(AndroidJUnit4::class)
 class ChangeRolesViewTest {
     @get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
 
     @Test
-    fun `click on back icon search not active emits the expected event`() {
+    fun `passing a 'USER' role throws an exception`() {
+        val exception = runCatching {
+            rule.setChangeRolesContent(
+                state = aChangeRolesState(
+                    role = RoomMember.Role.USER,
+                    eventSink = EnsureNeverCalledWithParam(),
+                ),
+            )
+        }.exceptionOrNull()
+
+        assertThat(exception).isNotNull()
+    }
+
+    @Test
+    fun `back key - with search active toggles the search`() {
         val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
-        rule.setChangeRolesView(
+        rule.setChangeRolesContent(
             state = aChangeRolesState(
+                isSearchActive = true,
                 eventSink = eventsRecorder,
             ),
         )
-        rule.pressBack()
-        eventsRecorder.assertList(
-            listOf(
-                ChangeRolesEvent.QueryChanged(""),
-                ChangeRolesEvent.Exit,
-            )
-        )
+
+        rule.pressBackKey()
+
+        eventsRecorder.assertSingle(ChangeRolesEvent.ToggleSearchActive)
     }
 
     @Test
-    fun `click on back icon search active  emits the expected event`() {
+    fun `back key - with search inactive exits the screen`() {
         val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
-        rule.setChangeRolesView(
+        rule.setChangeRolesContent(
             state = aChangeRolesState(
-                isSearchActive = true,
+                isSearchActive = false,
                 eventSink = eventsRecorder,
             ),
         )
-        rule.pressBack()
-        // This event should be there, maybe a problem with the SearchBar
-        // It's working fine in the app, so let's ignore it for now
-        // eventsRecorder.assertSingle(ChangeRolesEvent.ToggleSearchActive)
+
+        rule.pressBackKey()
+
+        eventsRecorder.assertList(listOf(ChangeRolesEvent.QueryChanged(""), ChangeRolesEvent.Exit))
     }
 
     @Test
-    fun `click on search bar emits the expected event`() {
+    fun `back button - exits the screen`() {
         val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
-        rule.setChangeRolesView(
+        rule.setChangeRolesContent(
             state = aChangeRolesState(
+                isSearchActive = false,
                 eventSink = eventsRecorder,
             ),
         )
-        rule.clickOn(CommonStrings.common_search_for_someone)
-        eventsRecorder.assertList(
-            listOf(
-                ChangeRolesEvent.QueryChanged(""),
-                // This event should be there, maybe a problem with the SearchBar
-                // It's working fine in the app, so let's ignore it for now
-                // ChangeRolesEvent.ToggleSearchActive,
-            )
-        )
+
+        rule.pressBack()
+
+        eventsRecorder.assertList(listOf(ChangeRolesEvent.QueryChanged(""), ChangeRolesEvent.Exit))
     }
 
     @Test
-    fun `click on save button emits the expected event`() {
+    fun `save button - with changes, it saves them`() {
         val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
-        rule.setChangeRolesView(
+        rule.setChangeRolesContent(
             state = aChangeRolesState(
                 hasPendingChanges = true,
                 eventSink = eventsRecorder,
             ),
         )
+
         rule.clickOn(CommonStrings.action_save)
-        eventsRecorder.assertList(
-            listOf(
-                ChangeRolesEvent.QueryChanged(""),
-                ChangeRolesEvent.Save,
-            )
-        )
+
+        eventsRecorder.assertList(listOf(ChangeRolesEvent.QueryChanged(""), ChangeRolesEvent.Save))
     }
 
     @Test
-    fun `testing exit confirmation dialog ok emits the expected event`() {
+    fun `save button - with no changes, does nothing`() {
         val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
-        rule.setChangeRolesView(
+        rule.setChangeRolesContent(
             state = aChangeRolesState(
-                exitState = AsyncAction.Confirming,
+                hasPendingChanges = false,
                 eventSink = eventsRecorder,
             ),
         )
-        rule.clickOn(CommonStrings.action_ok)
-        eventsRecorder.assertList(
-            listOf(
-                ChangeRolesEvent.QueryChanged(""),
-                ChangeRolesEvent.Exit,
-            )
-        )
+
+        rule.clickOn(CommonStrings.action_save)
+
+        eventsRecorder.assertList(listOf(ChangeRolesEvent.QueryChanged("")))
     }
 
     @Test
-    fun `testing exit confirmation dialog cancel emits the expected event`() {
+    fun `exit confirmation dialog - submit exits the screen`() {
         val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
-        rule.setChangeRolesView(
+        rule.setChangeRolesContent(
             state = aChangeRolesState(
+                isSearchActive = true,
                 exitState = AsyncAction.Confirming,
                 eventSink = eventsRecorder,
             ),
         )
-        rule.clickOn(CommonStrings.action_cancel)
-        eventsRecorder.assertList(
-            listOf(
-                ChangeRolesEvent.QueryChanged(""),
-                ChangeRolesEvent.CancelExit
-            )
-        )
+
+        rule.clickOn(CommonStrings.action_ok)
+
+        eventsRecorder.assertSingle(ChangeRolesEvent.Exit)
     }
 
     @Test
-    fun `testing saving dialog failure OK emits the expected event`() {
+    fun `exit confirmation dialog - cancel removes the dialog`() {
         val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
-        rule.setChangeRolesView(
+        rule.setChangeRolesContent(
             state = aChangeRolesState(
-                savingState = AsyncAction.Failure(Exception("boom")),
+                isSearchActive = true,
+                exitState = AsyncAction.Confirming,
                 eventSink = eventsRecorder,
             ),
         )
-        rule.clickOn(CommonStrings.action_ok)
-        eventsRecorder.assertList(
-            listOf(
-                ChangeRolesEvent.QueryChanged(""),
-                ChangeRolesEvent.ClearError,
-            )
-        )
+
+        rule.clickOn(CommonStrings.action_cancel)
+
+        eventsRecorder.assertSingle(ChangeRolesEvent.CancelExit)
     }
 
     @Test
-    fun `testing saving confirmation dialog for admin OK emits the expected event`() {
+    fun `save confirmation dialog - submit saves the changes`() {
         val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
-        rule.setChangeRolesView(
+        rule.setChangeRolesContent(
             state = aChangeRolesState(
                 role = RoomMember.Role.ADMIN,
+                isSearchActive = true,
                 savingState = AsyncAction.Confirming,
                 eventSink = eventsRecorder,
             ),
         )
+
         rule.clickOn(CommonStrings.action_ok)
-        eventsRecorder.assertList(
-            listOf(
-                ChangeRolesEvent.QueryChanged(""),
-                ChangeRolesEvent.Save,
-            )
-        )
+
+        eventsRecorder.assertSingle(ChangeRolesEvent.Save)
     }
 
     @Test
-    fun `testing saving confirmation dialog for admin cancel emits the expected event`() {
+    fun `save confirmation dialog - cancel removes the dialog`() {
         val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
-        rule.setChangeRolesView(
+        rule.setChangeRolesContent(
             state = aChangeRolesState(
                 role = RoomMember.Role.ADMIN,
+                isSearchActive = true,
                 savingState = AsyncAction.Confirming,
                 eventSink = eventsRecorder,
             ),
         )
+
         rule.clickOn(CommonStrings.action_cancel)
-        eventsRecorder.assertList(
-            listOf(
-                ChangeRolesEvent.QueryChanged(""),
-                ChangeRolesEvent.ClearError,
-            )
+
+        eventsRecorder.assertSingle(ChangeRolesEvent.ClearError)
+    }
+
+    @Test
+    fun `error dialog - dismissing removes the dialog`() {
+        val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
+        rule.setChangeRolesContent(
+            state = aChangeRolesState(
+                isSearchActive = true,
+                savingState = AsyncAction.Failure(IllegalStateException("boom")),
+                eventSink = eventsRecorder,
+            ),
         )
+
+        rule.clickOn(CommonStrings.action_ok)
+
+        eventsRecorder.assertSingle(ChangeRolesEvent.ClearError)
     }
 
     @Test
@@ -217,7 +231,7 @@ class ChangeRolesViewTest {
         val selectedUsers = aMatrixUserList().take(2)
         val userToDeselect = selectedUsers[1]
         assertThat(userToDeselect.displayName).isEqualTo("Bob")
-        rule.setChangeRolesView(
+        rule.setChangeRolesContent(
             state = aChangeRolesStateWithSelectedUsers().copy(
                 selectedUsers = selectedUsers.toImmutableList(),
                 eventSink = eventsRecorder,
@@ -235,6 +249,7 @@ class ChangeRolesViewTest {
     }
 
     @Test
+    @Config(qualifiers = "h1000dp")
     fun `testing adding user to the selected list emits the expected event`() {
         val eventsRecorder = EventsRecorder<ChangeRolesEvent>()
         val selectedUsers = aMatrixUserList().take(2)
@@ -242,12 +257,12 @@ class ChangeRolesViewTest {
             selectedUsers = selectedUsers.toImmutableList(),
             eventSink = eventsRecorder,
         )
-        val userToSelect = (state.searchResults as SearchBarResultState.Results).results[2].toMatrixUser()
+        val userToSelect = (state.searchResults as SearchBarResultState.Results).results.members.first().toMatrixUser()
         assertThat(userToSelect.displayName).isEqualTo("Carol")
-        rule.setChangeRolesView(
+        rule.setChangeRolesContent(
             state = state,
         )
-        // Select the user from the rom list
+        // Select the user from the row list
         rule.onNodeWithText("Carol").performClick()
         eventsRecorder.assertList(
             listOf(
@@ -265,9 +280,9 @@ class ChangeRolesViewTest {
             selectedUsers = selectedUsers.toImmutableList(),
             eventSink = eventsRecorder,
         )
-        val userToSelect = (state.searchResults as SearchBarResultState.Results).results[1].toMatrixUser()
+        val userToSelect = (state.searchResults as SearchBarResultState.Results).results.moderators.first().toMatrixUser()
         assertThat(userToSelect.displayName).isEqualTo("Bob")
-        rule.setChangeRolesView(
+        rule.setChangeRolesContent(
             state = state,
         )
         // Select the user from the rom list
@@ -279,16 +294,16 @@ class ChangeRolesViewTest {
             )
         )
     }
-}
 
-private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setChangeRolesView(
-    state: ChangeRolesState,
-    onBackPressed: () -> Unit = EnsureNeverCalled(),
-) {
-    setContent {
-        ChangeRolesView(
-            state = state,
-            onBackPressed = onBackPressed,
-        )
+    private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setChangeRolesContent(
+        state: ChangeRolesState,
+        onBackPressed: () -> Unit = EnsureNeverCalled(),
+    ) {
+        setContent {
+            ChangeRolesView(
+                state = state,
+                navigateUp = onBackPressed,
+            )
+        }
     }
 }
diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/rolesandpermissions/changeroles/MembersByRoleTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/rolesandpermissions/changeroles/MembersByRoleTest.kt
new file mode 100644
index 00000000000..7819745c524
--- /dev/null
+++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/rolesandpermissions/changeroles/MembersByRoleTest.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2024 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.element.android.features.roomdetails.rolesandpermissions.changeroles
+
+import com.google.common.truth.Truth.assertThat
+import io.element.android.features.roomdetails.impl.rolesandpermissions.changeroles.MembersByRole
+import io.element.android.libraries.matrix.api.room.RoomMember
+import io.element.android.libraries.matrix.test.A_USER_ID
+import io.element.android.libraries.matrix.test.A_USER_ID_2
+import io.element.android.libraries.matrix.test.A_USER_ID_3
+import io.element.android.libraries.matrix.test.A_USER_ID_4
+import io.element.android.libraries.matrix.test.A_USER_ID_5
+import io.element.android.libraries.matrix.test.room.aRoomMember
+import kotlinx.collections.immutable.persistentListOf
+import org.junit.Test
+
+class MembersByRoleTest {
+    @Test
+    fun `constructor - with single member list categorizes and sorts members`() {
+        val members = listOf(
+            aRoomMember(A_USER_ID_2, displayName = "Bob", role = RoomMember.Role.ADMIN),
+            aRoomMember(A_USER_ID, displayName = "Alice", role = RoomMember.Role.ADMIN),
+            aRoomMember(A_USER_ID_3, displayName = "Carol", role = RoomMember.Role.USER),
+            aRoomMember(A_USER_ID_5, displayName = "Eve", role = RoomMember.Role.USER),
+            aRoomMember(A_USER_ID_4, displayName = "David", role = RoomMember.Role.USER),
+        )
+        val membersByRole = MembersByRole(members = members)
+        assertThat(membersByRole.admins).containsExactly(
+            aRoomMember(A_USER_ID, displayName = "Alice", role = RoomMember.Role.ADMIN),
+            aRoomMember(A_USER_ID_2, displayName = "Bob", role = RoomMember.Role.ADMIN),
+        )
+        assertThat(membersByRole.moderators).isEmpty()
+        assertThat(membersByRole.members).containsExactly(
+            aRoomMember(A_USER_ID_3, displayName = "Carol", role = RoomMember.Role.USER),
+            aRoomMember(A_USER_ID_4, displayName = "David", role = RoomMember.Role.USER),
+            aRoomMember(A_USER_ID_5, displayName = "Eve", role = RoomMember.Role.USER),
+        )
+    }
+
+    @Test
+    fun `isEmpty - only returns true with no members of any role`() {
+        val emptyMembersByRole = MembersByRole(emptyList())
+        assertThat(emptyMembersByRole.isEmpty()).isTrue()
+
+        val membersByRoleWithAdmins = MembersByRole(
+            admins = persistentListOf(aRoomMember(A_USER_ID, role = RoomMember.Role.ADMIN)),
+            moderators = persistentListOf(),
+            members = persistentListOf(),
+        )
+        assertThat(membersByRoleWithAdmins.isEmpty()).isFalse()
+
+        val membersByRoleWithModerators = MembersByRole(
+            admins = persistentListOf(),
+            moderators = persistentListOf(aRoomMember(A_USER_ID, role = RoomMember.Role.MODERATOR)),
+            members = persistentListOf(),
+        )
+        assertThat(membersByRoleWithModerators.isEmpty()).isFalse()
+
+        val membersByRoleWithMembers = MembersByRole(
+            admins = persistentListOf(),
+            moderators = persistentListOf(),
+            members = persistentListOf(aRoomMember(A_USER_ID, role = RoomMember.Role.USER)),
+        )
+        assertThat(membersByRoleWithMembers.isEmpty()).isFalse()
+    }
+}
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_0,NEXUS_5,1.0,en].png
index 364d5ad96eb..91d3f82d6a6 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:3cf713ae66135179f17b52578bf4663bf34a102b92c0809c42e5285856d43f3b
-size 18257
+oid sha256:f9eb707bd20836dd80d1939a1eb405bbeca4b58aa36e9b627f3775cdffc9dcc0
+size 15142
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_1,NEXUS_5,1.0,en].png
index 6705985509c..fd7266592be 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:7737c502737b811720b54ba8e8db4248df8e0e8577435c61270853f92e65f6bc
-size 19731
+oid sha256:56873f51dd8de6630f5423f796687049a920bddafb5af17a47e4f901a5d9f360
+size 71767
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_10,NEXUS_5,1.0,en].png
index 8e48dd4ae91..bb978036ab5 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_10,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_10,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:1b0ca2b91bc525254ed4be526e622608f77d809a1c097ef02943d4cd751c65b2
-size 55941
+oid sha256:34efa87358c4529d0f67729fd417a3d52dc5a0031192dbf123bcc667d6e78391
+size 56803
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_2,NEXUS_5,1.0,en].png
index 205b4fe6237..05468c5c695 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:e96824d27d0fda0b183e8c90d659406d012861ff520f81cfa60374424137bbdb
-size 66079
+oid sha256:4818ed45a985359112ee92c38148f1030647ead270727525fed1cf1f5c493180
+size 66293
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_3,NEXUS_5,1.0,en].png
index d24aa840109..35c6953ca9e 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:b00d18ba4fa132e32c6580682c6b78d754d330735afcf8e4242ee0def213ba44
-size 66046
+oid sha256:57b0cd541704cd82962e03d2173bb37350d2f91bf1f3d6121314bdccad50c8e6
+size 66255
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_4,NEXUS_5,1.0,en].png
index 0eb57ff9d09..69680bab610 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_4,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_4,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:eeabb0a4ed645c7f47da62e7bafaca54ab1d3c5c48a195b48c3f807e5137d39c
-size 59992
+oid sha256:ebd6484e81803758298b4ff0e19a042918d85c29e3828a561c83328a9b3e4d73
+size 60644
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_5,NEXUS_5,1.0,en].png
index 40bc944f5a3..43f6b4f6589 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_5,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_5,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:5199d1491a315d7653b5e09049ead901650332deb50ec4d24742ac7f3f7ff535
-size 15618
+oid sha256:9e07c6ee5a1e9ebedc98ed8daca1c7e81c877102e24d9cc7a21834ce24df7d1d
+size 16758
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_6,NEXUS_5,1.0,en].png
index 11c72962574..f5a3dad0cb4 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_6,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_6,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:54461c606debb6867bd48a054f551dd56e2895530f06e6890b44ad7b1eeb9219
-size 65289
+oid sha256:77bca4e3380c63dba4e7def0937770c6d5b1ae5bde61e4743ecde035431fb8be
+size 64625
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_7,NEXUS_5,1.0,en].png
index b5a534c0d20..ac13b7852ab 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_7,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_7,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:66707e11931cc5824142a5f42ed95c4becd5621ea3a9c9cac3df5f0435b3883b
-size 66191
+oid sha256:b265ee7f4eb6c56e531004af6daae9ad89167b027d089fa960fc17553ec80131
+size 66783
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_8,NEXUS_5,1.0,en].png
index d74825b1b7b..996e749c1c7 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_8,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_8,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:31dcb5cef9f857e2b96631b4dd23a59a200c9174f8cc0e406d2a859497a8f893
-size 58934
+oid sha256:eb629e088198030a3a9a09c8cfc815a87e831dc6f5e26b225d17c61883585e50
+size 58902
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_9,NEXUS_5,1.0,en].png
index 7f712e5d7d1..0f822efc968 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_9,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Day-9_10_null_9,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:56e0b337fc6afdadf477785df479478ae24dd7c9cb1f98bedf33b920ad374e78
-size 69899
+oid sha256:f4dd6cbcd17c5c97c240a1244f3233f0f228612b317cc8f6b3f39a0d0d2b05fd
+size 70120
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_0,NEXUS_5,1.0,en].png
index 9c99ff605b2..95f73d3ca52 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:5a99d564c528dbcc2080b6f83ca09a97bd518412019d0f32b76b80086af4f17e
-size 16966
+oid sha256:4e47b753ec51c5cdc4640b9883bd9bbcb68af0c0ceacbc31020132213fb9bfbc
+size 14223
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_1,NEXUS_5,1.0,en].png
index 5e3ca5e6039..eb5a850bea2 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:eb3c08d58fd0dfa60ad1549b26a53f02239f1ca43aeda9e52350952d86d5fa74
-size 18178
+oid sha256:9d1cf36a65fc7e916a15a0a6eab4e5eaba47f8df5d39d5cb9fe75b137138a96d
+size 69609
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_10,NEXUS_5,1.0,en].png
index 9cd1a27f5ad..c34a2b7cf5e 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_10,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_10,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:f86fad7b780fb7fc0b36377724c6830d86c5d41dcfd50f8de8cbe9f40473e68d
-size 52719
+oid sha256:fa0b65d6cd2eac2746a2ba1598f075a6d5d144cfc62fbde8e7e17c5b69d85f1c
+size 53497
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_2,NEXUS_5,1.0,en].png
index afbfa647bf1..37e994e1965 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:00c4dba57e32a87d6acde138625214bb795c7e7c8987561d6ddd53fbf26674b5
-size 64446
+oid sha256:417ca17376f6e296a8955390c800191ebdccf8b358dbc738f438b70c2568606e
+size 64439
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_3,NEXUS_5,1.0,en].png
index cc77b40b160..a3490db6e3c 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:c3e270adac07c800c5ab1a124d564beee96b2e39e9473a69b8b90ff647bfd6df
-size 64184
+oid sha256:a73ae445a25011b1c376f93b7e7203b023e23a027aa2a44d109008a1cca98406
+size 64193
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_4,NEXUS_5,1.0,en].png
index 7615e4d3dea..34fda705fa6 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_4,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_4,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:6490597e92bd937451dbcf7d516f43525b5d18835cefec4f825fdf90ee6dc626
-size 57891
+oid sha256:a98762c06334da0cc53d04826623850b15d3fc5fdf7cdf8f50f896574a048d0d
+size 58356
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_5,NEXUS_5,1.0,en].png
index d0d83c7d167..b05af8072a3 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_5,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_5,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:5e088b944b00b462fcbaa16033a786835b8a09dd26f8a9b946580a237d2b363e
-size 15064
+oid sha256:b8188aab8aaa9d7685e6936883e635f097bc3b9b8fdd5bb778bc7baae3f97ea1
+size 16308
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_6,NEXUS_5,1.0,en].png
index 4eaec1e29eb..9f39eacc461 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_6,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_6,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:afac0f9958320d5c1f12d9b6647a15608eff51627dcb82d35ec9524a579f2637
-size 61111
+oid sha256:b6a02199d5c7b5bf4ff0251d437f071e2ce54440b1e0b4519305e0080f7ed6ec
+size 60375
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_7,NEXUS_5,1.0,en].png
index aad0cbf857e..85da1ba694f 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_7,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_7,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:3991def6f61df49c73e025a417680f1bd409d8e2aff41ba2434e3a5a50914665
-size 62128
+oid sha256:5898156b9c4ce053ab24728b0679bf6d2d0873459a7b1e4951f8f9ce646e4074
+size 62587
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_8,NEXUS_5,1.0,en].png
index 247ab0e9a61..b06975b0468 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_8,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_8,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:af3c14da68316feb82b4ae905868116239e43cb8b0e5393246efe0edd61f1bc2
-size 56497
+oid sha256:6648e7dc5c97e27efbf347380fc3ae3c67866595b086e1adefe36a274bf3afc2
+size 56314
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_9,NEXUS_5,1.0,en].png
index ad76d6153ea..cf1ca92dc61 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_9,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_null_ChangeRolesView-Night-9_11_null_9,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:1979b5b0dff66a05765a1ecd03d9a896d2aaf6dffc686ffd27bba3d5a0ac927a
-size 67254
+oid sha256:5d984c253b4990220acebfe91d33fb7f4201fb7a976bea48b2bc04e4788ddee2
+size 67263
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_null_PendingMemberRowWithLongName-Day-10_11_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_null_PendingMemberRowWithLongName-Day-10_11_null,NEXUS_5,1.0,en].png
new file mode 100644
index 00000000000..7f2ece3429f
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_null_PendingMemberRowWithLongName-Day-10_11_null,NEXUS_5,1.0,en].png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:31deb74551ce3e14d7fdbb6fad4bd1dd9c4124d50a39dcef572c1092eac75561
+size 16580
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_null_PendingMemberRowWithLongName-Night-10_12_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_null_PendingMemberRowWithLongName-Night-10_12_null,NEXUS_5,1.0,en].png
new file mode 100644
index 00000000000..f33d0577c49
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.changeroles_PendingMemberRowWithLongName_null_PendingMemberRowWithLongName-Night-10_12_null,NEXUS_5,1.0,en].png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e091e28939405c49558f40dbd291ace6280152b84e10676188b51f0ddc5a662d
+size 16104
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_0,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_0,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_0,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_1,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_1,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_1,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_2,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_2,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_2,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_3,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_3,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_3,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_4,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_4,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_4,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_5,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_5,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_5,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_6,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-10_11_null_6,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Day-11_12_null_6,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_0,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_0,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_0,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_1,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_1,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_1,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_2,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_2,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_2,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_3,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_3,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_3,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_4,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_4,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_4,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_5,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_5,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_5,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_6,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-10_12_null_6,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.roomdetails.impl.rolesandpermissions.permissions_ChangeRoomPermissionsView_null_ChangeRoomPermissionsView-Night-11_13_null_6,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-2_3_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-2_3_null_0,NEXUS_5,1.0,en].png
index 8eec21f31b4..dfe108c2a82 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-2_3_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-2_3_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:0a9321b5a4d15d815a690d422652d641deb24c06d49e99c5b28d3975544ec256
-size 40446
+oid sha256:bd35705e28bd0b46d2ca8752c3f338c883d5bc2e8c78af26c35eda435a6cf8cf
+size 42542
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-2_3_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-2_3_null_1,NEXUS_5,1.0,en].png
index 57e55da4674..d772d032e76 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-2_3_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-2_3_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:644e4ac9a9cdaf68cf3fe8b0d39fd46435d2074c384dbc68638703a6242af65d
-size 52111
+oid sha256:5bf4f3ff7ed970ba7eef2119525e800f80bfc056ccbd5345c1c610257180b50d
+size 53908
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-2_3_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-2_3_null_2,NEXUS_5,1.0,en].png
index 5e0e0776e41..bd69817bb85 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-2_3_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Day-2_3_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:b48d49a2c89c827ba3041738a01c4a665f694d904a1a4c8ad1aa6fbfcdc624de
-size 50508
+oid sha256:f963d37ac30795df5de921cef04b17de6baf45160716533984d08f6e543fb1e5
+size 52566
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-2_4_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-2_4_null_0,NEXUS_5,1.0,en].png
index 36699ada638..70ffe6c1d0b 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-2_4_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-2_4_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:1f0d40a93506c47240496c4fc7a1883aa69a964eb754f33c24b14cf877bc83cf
-size 38240
+oid sha256:1d1cd406230b94ba11e414aedfbe49d903d7aa54791c4dbd93616a9f16ca7068
+size 39917
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-2_4_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-2_4_null_1,NEXUS_5,1.0,en].png
index 68f38755924..712ed72f352 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-2_4_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-2_4_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:3556be4af59bd9815b6d8e57b1e7fb8b8e7985afe94cbf745e004f19373590b3
-size 48525
+oid sha256:7f9dbe41267a197887860cda4cef70138fd1e1b79497f396d1535725bc6219f4
+size 50262
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-2_4_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-2_4_null_2,NEXUS_5,1.0,en].png
index a53a3b3114d..a4af367f65d 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-2_4_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_null_SecureBackupEnterRecoveryKeyView-Night-2_4_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:cadda348b54958eb917c64ae03770c622b503393d2db9ae0af9e3abe9ee31d15
-size 47066
+oid sha256:02ebc69b55046c946142bac74f299d191b4dba2e175a670a67ed1e91dcaf51a8
+size 48753
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_10,NEXUS_5,1.0,en].png
index 8a9f1b5935c..80a305b6633 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_10,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_10,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:e643a714d2c527aa31ca716b3f4d9cc2423ad07b3615bbc274755e2ff90a73e4
-size 29035
+oid sha256:2c4aeacb175ef566e8093a9d7e297640739c71e488f0fe56f75803c2b98b09d2
+size 31137
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_11,NEXUS_5,1.0,en].png
index cba9218d611..f5d703685d1 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_11,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_11,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:4d28f1cb062b500452b353f35e8889a260e946807d8f1b5a04f5846ac4ad6482
-size 27511
+oid sha256:e7837d958cae6c7627a57a27880a00747dcebea7f00a8a29e4a0dcf67b5fae47
+size 29014
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_8,NEXUS_5,1.0,en].png
index 05b6946c0a1..d053778c553 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_8,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_8,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:05ee5bc12b1766b9aff8a1c0352e7f4cf2144487672add3fdb9d4c1d0f0b3c0f
-size 18954
+oid sha256:e7731621308a3392d0b940ce881171e909852d24787b63fbdbfea69e238c9f18
+size 20983
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_9,NEXUS_5,1.0,en].png
index b84ecb8f225..9d0b5ff5d93 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_9,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Day-6_7_null_9,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:6a6675dc88dabfc68848505be1115d25c34243b2bef0c11443c5bee1ae4b178c
-size 18760
+oid sha256:13e9687d249fd366e7d39cb20a49664ae661453f4a4333c3eb6334065211aa58
+size 20794
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_10,NEXUS_5,1.0,en].png
index 9872ca7ef99..cb364295aa1 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_10,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_10,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:bfe63f8ce9fcaeb7047cf0ae5e843151983f2f6edb10fff502c11589007c31b3
-size 27747
+oid sha256:ec7487af11bc617f04296a895351dd82e79a9acd2272225d2cf84a735a5bb30b
+size 29005
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_11,NEXUS_5,1.0,en].png
index 336ced708bf..bc7f0feec32 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_11,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_11,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:b6b4f5b67afae571b66cc0ad1bcdc5bca1c3f9903152897816011b8a7c87828e
-size 26009
+oid sha256:4120ab56b29285d4e2576563c521f59541d4368b9adcdc6c0dd997046df8a385
+size 27504
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_8,NEXUS_5,1.0,en].png
index 164a09669fc..5207d345515 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_8,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_8,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:23c85dd33bd5f865685545b2fa4682081eaff194da333a6801b46011d78a168a
-size 18313
+oid sha256:910d080a5abbba99a1347c77d70df982fe520239700cfbd04af460d33f5a0037
+size 20043
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_9,NEXUS_5,1.0,en].png
index 03941972b1e..b10ede074ef 100644
--- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_9,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.securebackup.impl.setup.views_RecoveryKeyView_null_RecoveryKeyView-Night-6_8_null_9,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:b8159ab16ad6e5ac1cdd4a604455084814369af2dc72e4e506eaf81799c234bc
-size 18030
+oid sha256:a77b0bb03a6941cf821420266c4922f9ef88c775ee6f8771aa17e966b3d86584
+size 19769