Use heroes to render room avatars

This commit is contained in:
Benoit Marty 2024-06-20 14:14:05 +02:00
parent 0754404aed
commit 99c90f1ced
6 changed files with 38 additions and 6 deletions

View file

@ -92,6 +92,7 @@ import io.element.android.libraries.matrix.ui.room.canRedactOwnAsState
import io.element.android.libraries.matrix.ui.room.canSendMessageAsState
import io.element.android.libraries.textcomposer.model.MessageComposerMode
import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -151,6 +152,9 @@ class MessagesPresenter @AssistedInject constructor(
val roomAvatar: AsyncData<AvatarData> by remember {
derivedStateOf { roomInfo?.avatarData()?.let { AsyncData.Success(it) } ?: AsyncData.Uninitialized }
}
val heroes by remember {
derivedStateOf { roomInfo?.heroes().orEmpty().toPersistentList() }
}
var hasDismissedInviteDialog by rememberSaveable {
mutableStateOf(false)
@ -217,6 +221,7 @@ class MessagesPresenter @AssistedInject constructor(
roomId = room.roomId,
roomName = roomName,
roomAvatar = roomAvatar,
heroes = heroes,
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
userHasPermissionToRedactOwn = userHasPermissionToRedactOwn,
userHasPermissionToRedactOther = userHasPermissionToRedactOther,
@ -250,6 +255,17 @@ class MessagesPresenter @AssistedInject constructor(
)
}
private fun MatrixRoomInfo.heroes(): List<AvatarData> {
return heroes.map { user ->
AvatarData(
id = user.userId.value,
name = user.displayName,
url = user.avatarUrl,
size = AvatarSize.TimelineRoom
)
}
}
private fun CoroutineScope.handleTimelineAction(
action: TimelineItemAction,
targetEvent: TimelineItem.Event,

View file

@ -29,12 +29,14 @@ import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
import io.element.android.libraries.matrix.api.core.RoomId
import kotlinx.collections.immutable.ImmutableList
@Immutable
data class MessagesState(
val roomId: RoomId,
val roomName: AsyncData<String>,
val roomAvatar: AsyncData<AvatarData>,
val heroes: ImmutableList<AvatarData>,
val userHasPermissionToSendMessage: Boolean,
val userHasPermissionToRedactOwn: Boolean,
val userHasPermissionToRedactOther: Boolean,

View file

@ -99,8 +99,8 @@ fun aMessagesState(
userHasPermissionToSendReaction: Boolean = true,
composerState: MessageComposerState = aMessageComposerState(
textEditorState = TextEditorState.Rich(aRichTextEditorState(initialText = "Hello", initialFocus = true)),
isFullScreen = false,
mode = MessageComposerMode.Normal,
isFullScreen = false,
mode = MessageComposerMode.Normal,
),
voiceMessageComposerState: VoiceMessageComposerState = aVoiceMessageComposerState(),
timelineState: TimelineState = aTimelineState(
@ -121,6 +121,7 @@ fun aMessagesState(
roomId = RoomId("!id:domain"),
roomName = roomName,
roomAvatar = roomAvatar,
heroes = persistentListOf(),
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
userHasPermissionToRedactOwn = userHasPermissionToRedactOwn,
userHasPermissionToRedactOther = userHasPermissionToRedactOther,

View file

@ -83,9 +83,9 @@ import io.element.android.libraries.androidutils.ui.hideKeyboard
import io.element.android.libraries.designsystem.atomic.molecules.IconTitlePlaceholdersRowMolecule
import io.element.android.libraries.designsystem.components.ProgressDialog
import io.element.android.libraries.designsystem.components.ProgressDialogType
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.avatar.CompositeAvatar
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.libraries.designsystem.preview.ElementPreview
@ -187,6 +187,7 @@ fun MessagesView(
MessagesViewTopBar(
roomName = state.roomName.dataOrNull(),
roomAvatar = state.roomAvatar.dataOrNull(),
heroes = state.heroes,
callState = state.callState,
onBackClick = {
// Since the textfield is now based on an Android view, this is no longer done automatically.
@ -442,6 +443,7 @@ private fun MessagesViewComposerBottomSheetContents(
private fun MessagesViewTopBar(
roomName: String?,
roomAvatar: AvatarData?,
heroes: List<AvatarData>,
callState: RoomCallState,
onRoomDetailsClick: () -> Unit,
onJoinCallClick: () -> Unit,
@ -457,6 +459,7 @@ private fun MessagesViewTopBar(
RoomAvatarAndNameRow(
roomName = roomName,
roomAvatar = roomAvatar,
heroes = heroes,
modifier = titleModifier
)
} else {
@ -500,13 +503,17 @@ private fun CallMenuItem(
private fun RoomAvatarAndNameRow(
roomName: String,
roomAvatar: AvatarData,
heroes: List<AvatarData>,
modifier: Modifier = Modifier
) {
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically
) {
Avatar(roomAvatar)
CompositeAvatar(
avatarData = roomAvatar,
heroes = heroes,
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = roomName,

View file

@ -53,7 +53,7 @@ import io.element.android.features.roomlist.impl.model.RoomListRoomSummaryProvid
import io.element.android.features.roomlist.impl.model.RoomSummaryDisplayType
import io.element.android.libraries.core.extensions.orEmpty
import io.element.android.libraries.designsystem.atomic.atoms.UnreadIndicatorAtom
import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.CompositeAvatar
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Button
@ -158,7 +158,10 @@ private fun RoomSummaryScaffoldRow(
.padding(horizontal = 16.dp, vertical = 11.dp)
.height(IntrinsicSize.Min),
) {
Avatar(room.avatarData)
CompositeAvatar(
avatarData = room.avatarData,
heroes = room.heroes,
)
Spacer(modifier = Modifier.width(16.dp))
Column(
modifier = Modifier.fillMaxWidth(),

View file

@ -23,6 +23,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_ROOM_NAME
import kotlinx.collections.immutable.toPersistentList
import org.junit.Test
class RoomListRoomSummaryTest {
@ -91,6 +92,7 @@ internal fun createRoomListRoomSummary(
userDefinedNotificationMode: RoomNotificationMode? = null,
isFavorite: Boolean = false,
displayType: RoomSummaryDisplayType = RoomSummaryDisplayType.ROOM,
heroes: List<AvatarData> = emptyList(),
) = RoomListRoomSummary(
id = A_ROOM_ID.value,
roomId = A_ROOM_ID,
@ -110,4 +112,5 @@ internal fun createRoomListRoomSummary(
canonicalAlias = null,
inviteSender = null,
isDm = false,
heroes = heroes.toPersistentList(),
)