Merge branch 'develop' into feature/fga/add_some_analytics

This commit is contained in:
ganfra 2024-02-19 17:52:16 +01:00
commit ac792006dd
86 changed files with 1322 additions and 381 deletions

View file

@ -55,6 +55,7 @@ fun aDmRoomMember(
powerLevel: Long = 0,
normalizedPowerLevel: Long = powerLevel,
isIgnored: Boolean = false,
role: RoomMember.Role = RoomMember.Role.USER,
) = RoomMember(
userId = userId,
displayName = displayName,
@ -64,6 +65,7 @@ fun aDmRoomMember(
powerLevel = powerLevel,
normalizedPowerLevel = normalizedPowerLevel,
isIgnored = isIgnored,
role = role,
)
fun aRoomDetailsState() = RoomDetailsState(

View file

@ -55,7 +55,10 @@ fun BlockUserDialogs(state: RoomMemberDetailsState) {
}
@Composable
private fun BlockConfirmationDialog(onBlockAction: () -> Unit, onDismiss: () -> Unit) {
private fun BlockConfirmationDialog(
onBlockAction: () -> Unit,
onDismiss: () -> Unit,
) {
ConfirmationDialog(
title = stringResource(R.string.screen_dm_details_block_user),
content = stringResource(R.string.screen_dm_details_block_alert_description),
@ -66,7 +69,10 @@ private fun BlockConfirmationDialog(onBlockAction: () -> Unit, onDismiss: () ->
}
@Composable
private fun UnblockConfirmationDialog(onUnblockAction: () -> Unit, onDismiss: () -> Unit) {
private fun UnblockConfirmationDialog(
onUnblockAction: () -> Unit,
onDismiss: () -> Unit,
) {
ConfirmationDialog(
title = stringResource(R.string.screen_dm_details_unblock_user),
content = stringResource(R.string.screen_dm_details_unblock_alert_description),

View file

@ -0,0 +1,38 @@
/*
* 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.impl.members
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.ui.room.sortingName
import java.text.Collator
// Comparator used to sort room members by power level (descending) and then by name (ascending)
internal class PowerLevelRoomMemberComparator : Comparator<RoomMember> {
// Used to simplify and compare unicode and ASCII chars (á == a)
private val collator = Collator.getInstance().apply {
decomposition = Collator.CANONICAL_DECOMPOSITION
}
override fun compare(o1: RoomMember, o2: RoomMember): Int {
return when {
o1.powerLevel > o2.powerLevel -> return -1
o1.powerLevel < o2.powerLevel -> return 1
else -> {
collator.compare(o1.sortingName(), o2.sortingName())
}
}
}
}

View file

@ -66,7 +66,9 @@ class RoomMemberListPresenter @Inject constructor(
roomMembers = AsyncData.Success(
RoomMembers(
invited = members.getOrDefault(RoomMembershipState.INVITE, emptyList()).toImmutableList(),
joined = members.getOrDefault(RoomMembershipState.JOIN, emptyList()).toImmutableList(),
joined = members.getOrDefault(RoomMembershipState.JOIN, emptyList())
.sortedWith(PowerLevelRoomMemberComparator())
.toImmutableList(),
)
)
}
@ -84,7 +86,9 @@ class RoomMemberListPresenter @Inject constructor(
SearchBarResultState.Results(
RoomMembers(
invited = results.getOrDefault(RoomMembershipState.INVITE, emptyList()).toImmutableList(),
joined = results.getOrDefault(RoomMembershipState.JOIN, emptyList()).toImmutableList(),
joined = results.getOrDefault(RoomMembershipState.JOIN, emptyList())
.sortedWith(PowerLevelRoomMemberComparator())
.toImmutableList(),
)
)
}

View file

@ -31,7 +31,7 @@ internal class RoomMemberListStateProvider : PreviewParameterProvider<RoomMember
roomMembers = AsyncData.Success(
RoomMembers(
invited = persistentListOf(aVictor(), aWalter()),
joined = persistentListOf(anAlice(), aBob()),
joined = persistentListOf(anAlice(), aBob(), aWalter()),
)
)
),
@ -79,6 +79,7 @@ fun aRoomMember(
powerLevel: Long = 0L,
normalizedPowerLevel: Long = 0L,
isIgnored: Boolean = false,
role: RoomMember.Role = RoomMember.Role.USER,
) = RoomMember(
userId = userId,
displayName = displayName,
@ -88,6 +89,7 @@ fun aRoomMember(
powerLevel = powerLevel,
normalizedPowerLevel = normalizedPowerLevel,
isIgnored = isIgnored,
role = role,
)
fun aRoomMemberList() = persistentListOf(
@ -103,8 +105,8 @@ fun aRoomMemberList() = persistentListOf(
aWalter(),
)
fun anAlice() = aRoomMember(UserId("@alice:server.org"), "Alice")
fun aBob() = aRoomMember(UserId("@bob:server.org"), "Bob")
fun anAlice() = aRoomMember(UserId("@alice:server.org"), "Alice", role = RoomMember.Role.ADMIN)
fun aBob() = aRoomMember(UserId("@bob:server.org"), "Bob", role = RoomMember.Role.MODERATOR)
fun aVictor() = aRoomMember(UserId("@victor:server.org"), "Victor", membership = RoomMembershipState.INVITE)

View file

@ -177,14 +177,28 @@ private fun RoomMemberListItem(
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
val roleText = when (roomMember.role) {
RoomMember.Role.ADMIN -> stringResource(R.string.screen_room_member_list_role_administrator)
RoomMember.Role.MODERATOR -> stringResource(R.string.screen_room_member_list_role_moderator)
RoomMember.Role.USER -> null
}
MatrixUserRow(
modifier = modifier.clickable(onClick = onClick),
matrixUser = MatrixUser(
userId = roomMember.userId,
displayName = roomMember.displayName,
avatarUrl = roomMember.avatarUrl
avatarUrl = roomMember.avatarUrl,
),
avatarSize = AvatarSize.UserListItem,
trailingContent = roleText?.let {
@Composable {
Text(
text = it,
style = ElementTheme.typography.fontBodySmRegular,
color = ElementTheme.colors.textSecondary,
)
}
}
)
}

View file

@ -19,28 +19,38 @@ package io.element.android.features.roomdetails.impl.members.details
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.core.RoomId
open class RoomMemberDetailsStateProvider : PreviewParameterProvider<RoomMemberDetailsState> {
override val values: Sequence<RoomMemberDetailsState>
get() = sequenceOf(
aRoomMemberDetailsState(),
aRoomMemberDetailsState().copy(userName = null),
aRoomMemberDetailsState().copy(isBlocked = AsyncData.Success(true)),
aRoomMemberDetailsState().copy(displayConfirmationDialog = RoomMemberDetailsState.ConfirmationDialog.Block),
aRoomMemberDetailsState().copy(displayConfirmationDialog = RoomMemberDetailsState.ConfirmationDialog.Unblock),
aRoomMemberDetailsState().copy(isBlocked = AsyncData.Loading(true)),
aRoomMemberDetailsState().copy(startDmActionState = AsyncAction.Loading),
aRoomMemberDetailsState(userName = null),
aRoomMemberDetailsState(isBlocked = AsyncData.Success(true)),
aRoomMemberDetailsState(displayConfirmationDialog = RoomMemberDetailsState.ConfirmationDialog.Block),
aRoomMemberDetailsState(displayConfirmationDialog = RoomMemberDetailsState.ConfirmationDialog.Unblock),
aRoomMemberDetailsState(isBlocked = AsyncData.Loading(true)),
aRoomMemberDetailsState(startDmActionState = AsyncAction.Loading),
// Add other states here
)
}
fun aRoomMemberDetailsState() = RoomMemberDetailsState(
userId = "@daniel:domain.com",
userName = "Daniel",
avatarUrl = null,
isBlocked = AsyncData.Success(false),
startDmActionState = AsyncAction.Uninitialized,
displayConfirmationDialog = null,
isCurrentUser = false,
eventSink = {},
fun aRoomMemberDetailsState(
userId: String = "@daniel:domain.com",
userName: String? = "Daniel",
avatarUrl: String? = null,
isBlocked: AsyncData<Boolean> = AsyncData.Success(false),
startDmActionState: AsyncAction<RoomId> = AsyncAction.Uninitialized,
displayConfirmationDialog: RoomMemberDetailsState.ConfirmationDialog? = null,
isCurrentUser: Boolean = false,
eventSink: (RoomMemberDetailsEvents) -> Unit = {},
) = RoomMemberDetailsState(
userId = userId,
userName = userName,
avatarUrl = avatarUrl,
isBlocked = isBlocked,
startDmActionState = startDmActionState,
displayConfirmationDialog = displayConfirmationDialog,
isCurrentUser = isCurrentUser,
eventSink = eventSink,
)