Use heroes to render room avatars
This commit is contained in:
parent
8aa7afd480
commit
042ba6b35e
6 changed files with 38 additions and 6 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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…
Add table
Add a link
Reference in a new issue