Merge pull request #2027 from element-hq/feature/bma/openRoomAvatar
Feature/bma/open room avatar
This commit is contained in:
1
changelog.d/1918.misc
Normal file
1
changelog.d/1918.misc
Normal file
@@ -0,0 +1 @@
|
||||
Add ability to see the room avatar in the media viewer.
|
||||
@@ -242,7 +242,6 @@ class MessagesFlowNode @AssistedInject constructor(
|
||||
backstack.push(navTarget)
|
||||
}
|
||||
is TimelineItemVideoContent -> {
|
||||
val mediaSource = event.content.videoSource
|
||||
val navTarget = NavTarget.MediaViewer(
|
||||
mediaInfo = MediaInfo(
|
||||
name = event.content.body,
|
||||
@@ -250,13 +249,12 @@ class MessagesFlowNode @AssistedInject constructor(
|
||||
formattedFileSize = event.content.formattedFileSize,
|
||||
fileExtension = event.content.fileExtension
|
||||
),
|
||||
mediaSource = mediaSource,
|
||||
mediaSource = event.content.videoSource,
|
||||
thumbnailSource = event.content.thumbnailSource,
|
||||
)
|
||||
backstack.push(navTarget)
|
||||
}
|
||||
is TimelineItemFileContent -> {
|
||||
val mediaSource = event.content.fileSource
|
||||
val navTarget = NavTarget.MediaViewer(
|
||||
mediaInfo = MediaInfo(
|
||||
name = event.content.body,
|
||||
@@ -264,13 +262,12 @@ class MessagesFlowNode @AssistedInject constructor(
|
||||
formattedFileSize = event.content.formattedFileSize,
|
||||
fileExtension = event.content.fileExtension
|
||||
),
|
||||
mediaSource = mediaSource,
|
||||
mediaSource = event.content.fileSource,
|
||||
thumbnailSource = event.content.thumbnailSource,
|
||||
)
|
||||
backstack.push(navTarget)
|
||||
}
|
||||
is TimelineItemAudioContent -> {
|
||||
val mediaSource = event.content.mediaSource
|
||||
val navTarget = NavTarget.MediaViewer(
|
||||
mediaInfo = MediaInfo(
|
||||
name = event.content.body,
|
||||
@@ -278,7 +275,7 @@ class MessagesFlowNode @AssistedInject constructor(
|
||||
formattedFileSize = event.content.formattedFileSize,
|
||||
fileExtension = event.content.fileExtension
|
||||
),
|
||||
mediaSource = mediaSource,
|
||||
mediaSource = event.content.mediaSource,
|
||||
thumbnailSource = null,
|
||||
)
|
||||
backstack.push(navTarget)
|
||||
|
||||
@@ -34,7 +34,7 @@ import io.element.android.features.roomdetails.impl.edit.RoomDetailsEditNode
|
||||
import io.element.android.features.roomdetails.impl.invite.RoomInviteMembersNode
|
||||
import io.element.android.features.roomdetails.impl.members.RoomMemberListNode
|
||||
import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsNode
|
||||
import io.element.android.features.roomdetails.impl.members.details.avatar.RoomMemberAvatarPreviewNode
|
||||
import io.element.android.features.roomdetails.impl.members.details.avatar.AvatarPreviewNode
|
||||
import io.element.android.features.roomdetails.impl.notificationsettings.RoomNotificationSettingsNode
|
||||
import io.element.android.libraries.architecture.BackstackNode
|
||||
import io.element.android.libraries.architecture.animation.rememberDefaultTransitionHandler
|
||||
@@ -87,7 +87,7 @@ class RoomDetailsFlowNode @AssistedInject constructor(
|
||||
data class RoomMemberDetails(val roomMemberId: UserId) : NavTarget
|
||||
|
||||
@Parcelize
|
||||
data class MemberAvatarPreview(val userName: String, val avatarUrl: String) : NavTarget
|
||||
data class AvatarPreview(val name: String, val avatarUrl: String) : NavTarget
|
||||
}
|
||||
|
||||
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
|
||||
@@ -110,8 +110,8 @@ class RoomDetailsFlowNode @AssistedInject constructor(
|
||||
backstack.push(NavTarget.RoomNotificationSettings(showUserDefinedSettingStyle = false))
|
||||
}
|
||||
|
||||
override fun openAvatarPreview(username: String, url: String) {
|
||||
backstack.push(NavTarget.MemberAvatarPreview(username, url))
|
||||
override fun openAvatarPreview(name: String, url: String) {
|
||||
backstack.push(NavTarget.AvatarPreview(name, url))
|
||||
}
|
||||
}
|
||||
createNode<RoomDetailsNode>(buildContext, listOf(roomDetailsCallback))
|
||||
@@ -151,7 +151,7 @@ class RoomDetailsFlowNode @AssistedInject constructor(
|
||||
is NavTarget.RoomMemberDetails -> {
|
||||
val callback = object : RoomMemberDetailsNode.Callback {
|
||||
override fun openAvatarPreview(username: String, avatarUrl: String) {
|
||||
backstack.push(NavTarget.MemberAvatarPreview(username, avatarUrl))
|
||||
backstack.push(NavTarget.AvatarPreview(username, avatarUrl))
|
||||
}
|
||||
|
||||
override fun onStartDM(roomId: RoomId) {
|
||||
@@ -161,22 +161,22 @@ class RoomDetailsFlowNode @AssistedInject constructor(
|
||||
val plugins = listOf(RoomMemberDetailsNode.RoomMemberDetailsInput(navTarget.roomMemberId), callback)
|
||||
createNode<RoomMemberDetailsNode>(buildContext, plugins)
|
||||
}
|
||||
is NavTarget.MemberAvatarPreview -> {
|
||||
is NavTarget.AvatarPreview -> {
|
||||
// We need to fake the MimeType here for the viewer to work.
|
||||
val mimeType = MimeTypes.Images
|
||||
val input = MediaViewerNode.Inputs(
|
||||
mediaInfo = MediaInfo(
|
||||
name = navTarget.userName,
|
||||
name = navTarget.name,
|
||||
mimeType = mimeType,
|
||||
formattedFileSize = "",
|
||||
fileExtension = ""
|
||||
),
|
||||
mediaSource = MediaSource(url = navTarget.avatarUrl),
|
||||
thumbnailSource = MediaSource(url = navTarget.avatarUrl),
|
||||
thumbnailSource = null,
|
||||
canDownload = false,
|
||||
canShare = false,
|
||||
)
|
||||
createNode<RoomMemberAvatarPreviewNode>(buildContext, listOf(input))
|
||||
createNode<AvatarPreviewNode>(buildContext, listOf(input))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class RoomDetailsNode @AssistedInject constructor(
|
||||
fun openInviteMembers()
|
||||
fun editRoomDetails()
|
||||
fun openRoomNotificationSettings()
|
||||
fun openAvatarPreview(username: String, url: String)
|
||||
fun openAvatarPreview(name: String, url: String)
|
||||
}
|
||||
|
||||
private val callbacks = plugins<Callback>()
|
||||
@@ -111,8 +111,8 @@ class RoomDetailsNode @AssistedInject constructor(
|
||||
callbacks.forEach { it.editRoomDetails() }
|
||||
}
|
||||
|
||||
private fun openAvatarPreview(username: String, url: String) {
|
||||
callbacks.forEach { it.openAvatarPreview(username, url) }
|
||||
private fun openAvatarPreview(name: String, url: String) {
|
||||
callbacks.forEach { it.openAvatarPreview(name, url) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package io.element.android.features.roomdetails.impl
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -77,6 +78,7 @@ import io.element.android.libraries.designsystem.theme.components.TopAppBar
|
||||
import io.element.android.libraries.designsystem.utils.CommonDrawables
|
||||
import io.element.android.libraries.matrix.api.room.RoomMember
|
||||
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
|
||||
import io.element.android.libraries.matrix.api.room.getBestName
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
@@ -89,7 +91,7 @@ fun RoomDetailsView(
|
||||
openRoomMemberList: () -> Unit,
|
||||
openRoomNotificationSettings: () -> Unit,
|
||||
invitePeople: () -> Unit,
|
||||
openAvatarPreview: (username: String, url: String) -> Unit,
|
||||
openAvatarPreview: (name: String, url: String) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
fun onShareMember() {
|
||||
@@ -120,7 +122,10 @@ fun RoomDetailsView(
|
||||
avatarUrl = state.roomAvatarUrl,
|
||||
roomId = state.roomId,
|
||||
roomName = state.roomName,
|
||||
roomAlias = state.roomAlias
|
||||
roomAlias = state.roomAlias,
|
||||
openAvatarPreview = { avatarUrl ->
|
||||
openAvatarPreview(state.roomName, avatarUrl)
|
||||
},
|
||||
)
|
||||
MainActionsSection(
|
||||
state = state,
|
||||
@@ -134,10 +139,8 @@ fun RoomDetailsView(
|
||||
avatarUrl = state.roomAvatarUrl ?: member.avatarUrl,
|
||||
userId = member.userId.value,
|
||||
userName = state.roomName,
|
||||
openAvatarPreview = {
|
||||
if (member.avatarUrl != null) {
|
||||
openAvatarPreview(member.displayName ?: member.userId.value, member.avatarUrl!!)
|
||||
}
|
||||
openAvatarPreview = { avatarUrl ->
|
||||
openAvatarPreview(member.getBestName(), avatarUrl)
|
||||
},
|
||||
)
|
||||
RoomMemberMainActionsSection(onShareUser = ::onShareMember)
|
||||
@@ -265,6 +268,7 @@ private fun RoomHeaderSection(
|
||||
roomId: String,
|
||||
roomName: String,
|
||||
roomAlias: String?,
|
||||
openAvatarPreview: (url: String) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(
|
||||
@@ -275,7 +279,9 @@ private fun RoomHeaderSection(
|
||||
) {
|
||||
Avatar(
|
||||
avatarData = AvatarData(roomId, roomName, avatarUrl, AvatarSize.RoomHeader),
|
||||
modifier = Modifier.size(70.dp)
|
||||
modifier = Modifier
|
||||
.size(70.dp)
|
||||
.clickable(enabled = avatarUrl != null) { openAvatarPreview(avatarUrl!!) }
|
||||
)
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
Text(
|
||||
|
||||
@@ -26,7 +26,7 @@ import io.element.android.libraries.mediaviewer.api.viewer.MediaViewerNode
|
||||
import io.element.android.libraries.mediaviewer.api.viewer.MediaViewerPresenter
|
||||
|
||||
@ContributesNode(RoomScope::class)
|
||||
class RoomMemberAvatarPreviewNode @AssistedInject constructor(
|
||||
class AvatarPreviewNode @AssistedInject constructor(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
presenterFactory: MediaViewerPresenter.Factory,
|
||||
@@ -32,3 +32,7 @@ data class RoomMember(
|
||||
enum class RoomMembershipState {
|
||||
BAN, INVITE, JOIN, KNOCK, LEAVE
|
||||
}
|
||||
|
||||
fun RoomMember.getBestName(): String {
|
||||
return displayName?.takeIf { it.isNotEmpty() } ?: userId.value
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user