Room admins can change user roles (#2423)

Allow Admins to modify room member roles:

- Add a 'roles and permissions' option for each room.
- Allow promoting users to admins, adding or removing moderators, and demote yourself if you're and admin.

---------

Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
Jorge Martin Espinosa 2024-03-05 17:46:47 +01:00 committed by GitHub
parent 1d892b4bc8
commit b9d902e3fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
110 changed files with 2398 additions and 160 deletions

View file

@ -19,7 +19,6 @@ package io.element.android.features.createroom.impl.addpeople
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.createroom.impl.userlist.SelectionMode
import io.element.android.features.createroom.impl.userlist.UserListState
import io.element.android.features.createroom.impl.userlist.aListOfSelectedUsers
import io.element.android.features.createroom.impl.userlist.aUserListState
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.matrix.ui.components.aMatrixUserList
@ -32,7 +31,7 @@ open class AddPeopleUserListStateProvider : PreviewParameterProvider<UserListSta
aUserListState(),
aUserListState().copy(
searchResults = SearchBarResultState.Results(aMatrixUserList().toImmutableList()),
selectedUsers = aListOfSelectedUsers(),
selectedUsers = aMatrixUserList().toImmutableList(),
isSearchActive = false,
selectionMode = SelectionMode.Multiple,
),
@ -44,7 +43,7 @@ open class AddPeopleUserListStateProvider : PreviewParameterProvider<UserListSta
}
.toImmutableList()
),
selectedUsers = aListOfSelectedUsers(),
selectedUsers = aMatrixUserList().toImmutableList(),
isSearchActive = true,
selectionMode = SelectionMode.Multiple,
)

View file

@ -40,7 +40,7 @@ import io.element.android.libraries.designsystem.theme.components.HorizontalDivi
import io.element.android.libraries.designsystem.theme.components.SearchBar
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.components.SelectedUsersList
import io.element.android.libraries.matrix.ui.components.SelectedUsersRowList
import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.libraries.usersearch.api.UserSearchResult
import kotlinx.collections.immutable.ImmutableList
@ -92,7 +92,7 @@ fun SearchUserBar(
animationSpec = spring(stiffness = Spring.StiffnessMediumLow)
)
SelectedUsersList(
SelectedUsersRowList(
contentPadding = PaddingValues(16.dp),
selectedUsers = selectedUsers,
autoScroll = true,
@ -114,7 +114,7 @@ fun SearchUserBar(
SearchMultipleUsersResultItem(
modifier = Modifier.fillMaxWidth(),
searchResult = searchResult,
isUserSelected = selectedUsers.find { it.userId == searchResult.matrixUser.userId } != null,
isUserSelected = selectedUsers.contains(searchResult.matrixUser),
onCheckedChange = { checked ->
if (checked) {
onUserSelected(searchResult.matrixUser)

View file

@ -29,7 +29,7 @@ import io.element.android.features.createroom.impl.userlist.UserListStateProvide
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.components.SelectedUsersList
import io.element.android.libraries.matrix.ui.components.SelectedUsersRowList
@Composable
fun UserListView(
@ -64,7 +64,7 @@ fun UserListView(
)
if (state.isMultiSelectionEnabled && !state.isSearchActive && state.selectedUsers.isNotEmpty()) {
SelectedUsersList(
SelectedUsersRowList(
contentPadding = PaddingValues(16.dp),
selectedUsers = state.selectedUsers,
autoScroll = true,

View file

@ -18,10 +18,11 @@ package io.element.android.features.createroom.impl.configureroom
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.createroom.impl.CreateRoomConfig
import io.element.android.features.createroom.impl.userlist.aListOfSelectedUsers
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.ui.components.aMatrixUserList
import io.element.android.libraries.permissions.api.aPermissionsState
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
open class ConfigureRoomStateProvider : PreviewParameterProvider<ConfigureRoomState> {
override val values: Sequence<ConfigureRoomState>
@ -31,7 +32,7 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider<ConfigureRoomSt
config = CreateRoomConfig(
roomName = "Room 101",
topic = "Room topic for this room when the text goes onto multiple lines and is really long, there shouldnt be more than 3 lines",
invites = aListOfSelectedUsers(),
invites = aMatrixUserList().toImmutableList(),
privacy = RoomPrivacy.Public,
),
),

View file

@ -59,7 +59,7 @@ 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.RoomId
import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
import io.element.android.libraries.matrix.ui.components.SelectedUsersList
import io.element.android.libraries.matrix.ui.components.SelectedUsersRowList
import io.element.android.libraries.matrix.ui.components.UnsavedAvatar
import io.element.android.libraries.permissions.api.PermissionsView
import io.element.android.libraries.ui.strings.CommonStrings
@ -120,7 +120,7 @@ fun ConfigureRoomView(
onTopicChanged = { state.eventSink(ConfigureRoomEvents.TopicChanged(it)) },
)
if (state.config.invites.isNotEmpty()) {
SelectedUsersList(
SelectedUsersRowList(
modifier = Modifier.padding(bottom = 16.dp),
contentPadding = PaddingValues(horizontal = 24.dp),
selectedUsers = state.config.invites,

View file

@ -25,7 +25,7 @@ class UserListDataStore @Inject constructor() {
private val selectedUsers: MutableStateFlow<List<MatrixUser>> = MutableStateFlow(emptyList())
fun selectUser(user: MatrixUser) {
if (user !in selectedUsers.value) {
if (!selectedUsers.value.contains(user)) {
selectedUsers.tryEmit(selectedUsers.value.plus(user))
}
}

View file

@ -19,7 +19,6 @@ package io.element.android.features.createroom.impl.userlist
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.matrix.ui.components.aMatrixUserList
import io.element.android.libraries.usersearch.api.UserSearchResult
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
@ -38,15 +37,15 @@ open class UserListStateProvider : PreviewParameterProvider<UserListState> {
aUserListState().copy(
isSearchActive = true,
searchQuery = "@someone:matrix.org",
selectedUsers = aListOfSelectedUsers(),
searchResults = SearchBarResultState.Results(aMatrixUserList().map { UserSearchResult(it) }.toImmutableList()),
selectedUsers = aMatrixUserList().toImmutableList(),
searchResults = SearchBarResultState.Results(aListOfSelectedUsers()),
),
aUserListState().copy(
isSearchActive = true,
searchQuery = "@someone:matrix.org",
selectionMode = SelectionMode.Multiple,
selectedUsers = aListOfSelectedUsers(),
searchResults = SearchBarResultState.Results(aMatrixUserList().map { UserSearchResult(it) }.toImmutableList()),
selectedUsers = aMatrixUserList().toImmutableList(),
searchResults = SearchBarResultState.Results(aListOfSelectedUsers()),
),
aUserListState().copy(
isSearchActive = true,