Browse Source

Use heroes to render room avatars

pull/3058/head
Benoit Marty 3 months ago
parent
commit
99c90f1ced
  1. 16
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt
  2. 2
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt
  3. 5
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt
  4. 11
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt
  5. 7
      features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt
  6. 3
      features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryTest.kt

16
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt

@ -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.matrix.ui.room.canSendMessageAsState
import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.libraries.textcomposer.model.MessageComposerMode
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -151,6 +152,9 @@ class MessagesPresenter @AssistedInject constructor(
val roomAvatar: AsyncData<AvatarData> by remember { val roomAvatar: AsyncData<AvatarData> by remember {
derivedStateOf { roomInfo?.avatarData()?.let { AsyncData.Success(it) } ?: AsyncData.Uninitialized } derivedStateOf { roomInfo?.avatarData()?.let { AsyncData.Success(it) } ?: AsyncData.Uninitialized }
} }
val heroes by remember {
derivedStateOf { roomInfo?.heroes().orEmpty().toPersistentList() }
}
var hasDismissedInviteDialog by rememberSaveable { var hasDismissedInviteDialog by rememberSaveable {
mutableStateOf(false) mutableStateOf(false)
@ -217,6 +221,7 @@ class MessagesPresenter @AssistedInject constructor(
roomId = room.roomId, roomId = room.roomId,
roomName = roomName, roomName = roomName,
roomAvatar = roomAvatar, roomAvatar = roomAvatar,
heroes = heroes,
userHasPermissionToSendMessage = userHasPermissionToSendMessage, userHasPermissionToSendMessage = userHasPermissionToSendMessage,
userHasPermissionToRedactOwn = userHasPermissionToRedactOwn, userHasPermissionToRedactOwn = userHasPermissionToRedactOwn,
userHasPermissionToRedactOther = userHasPermissionToRedactOther, 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( private fun CoroutineScope.handleTimelineAction(
action: TimelineItemAction, action: TimelineItemAction,
targetEvent: TimelineItem.Event, targetEvent: TimelineItem.Event,

2
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt

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

5
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt

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

11
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt

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

7
features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt

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

3
features/roomlist/impl/src/test/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryTest.kt

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

Loading…
Cancel
Save