From 760000aa67a083ff2c5ed14e7eb8e0f4e1a67a0b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Dec 2023 15:05:59 +0100 Subject: [PATCH 1/8] Open room Avatar on click #1918 --- .../features/roomdetails/impl/RoomDetailsView.kt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index 9c7151d4af..decbfb8b23 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -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 @@ -120,7 +121,12 @@ fun RoomDetailsView( avatarUrl = state.roomAvatarUrl, roomId = state.roomId, roomName = state.roomName, - roomAlias = state.roomAlias + roomAlias = state.roomAlias, + openAvatarPreview = { + if (state.roomAvatarUrl != null) { + openAvatarPreview(state.roomName, state.roomAvatarUrl) + } + }, ) MainActionsSection( state = state, @@ -265,6 +271,7 @@ private fun RoomHeaderSection( roomId: String, roomName: String, roomAlias: String?, + openAvatarPreview: (url: String) -> Unit, modifier: Modifier = Modifier ) { Column( @@ -275,7 +282,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( From 48e9464d0029d11048ba9c996935f936c3c17c33 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Dec 2023 15:08:54 +0100 Subject: [PATCH 2/8] Cleanup --- .../features/roomdetails/impl/RoomDetailsView.kt | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index decbfb8b23..a9eea1d27d 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -122,10 +122,8 @@ fun RoomDetailsView( roomId = state.roomId, roomName = state.roomName, roomAlias = state.roomAlias, - openAvatarPreview = { - if (state.roomAvatarUrl != null) { - openAvatarPreview(state.roomName, state.roomAvatarUrl) - } + openAvatarPreview = { avatarUrl -> + openAvatarPreview(state.roomName, avatarUrl) }, ) MainActionsSection( @@ -140,10 +138,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.displayName ?: member.userId.value, avatarUrl) }, ) RoomMemberMainActionsSection(onShareUser = ::onShareMember) From e4ba9c1d5abce4c76f25d6f4bf79552c81be7157 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Dec 2023 15:10:49 +0100 Subject: [PATCH 3/8] Create RoomMember.getBestName() extension. --- .../android/features/roomdetails/impl/RoomDetailsView.kt | 3 ++- .../element/android/libraries/matrix/api/room/RoomMember.kt | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index a9eea1d27d..042ba2f71e 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -78,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 @@ -139,7 +140,7 @@ fun RoomDetailsView( userId = member.userId.value, userName = state.roomName, openAvatarPreview = { avatarUrl -> - openAvatarPreview(member.displayName ?: member.userId.value, avatarUrl) + openAvatarPreview(member.getBestName(), avatarUrl) }, ) RoomMemberMainActionsSection(onShareUser = ::onShareMember) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomMember.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomMember.kt index 3c9bd030b0..54c00572c5 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomMember.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomMember.kt @@ -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 +} From cbd045aa9429ec34e436ab84d7e95dc49d87d34a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Dec 2023 15:13:10 +0100 Subject: [PATCH 4/8] Do some renaming, since it can now also be room avatar. --- .../features/roomdetails/impl/RoomDetailsFlowNode.kt | 12 ++++++------ ...mberAvatarPreviewNode.kt => AvatarPreviewNode.kt} | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) rename features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/avatar/{RoomMemberAvatarPreviewNode.kt => AvatarPreviewNode.kt} (95%) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt index 27ddf47f92..adab05262a 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt @@ -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 userName: String, val avatarUrl: String) : NavTarget } override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { @@ -111,7 +111,7 @@ class RoomDetailsFlowNode @AssistedInject constructor( } override fun openAvatarPreview(username: String, url: String) { - backstack.push(NavTarget.MemberAvatarPreview(username, url)) + backstack.push(NavTarget.AvatarPreview(username, url)) } } createNode(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,7 +161,7 @@ class RoomDetailsFlowNode @AssistedInject constructor( val plugins = listOf(RoomMemberDetailsNode.RoomMemberDetailsInput(navTarget.roomMemberId), callback) createNode(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( @@ -176,7 +176,7 @@ class RoomDetailsFlowNode @AssistedInject constructor( canDownload = false, canShare = false, ) - createNode(buildContext, listOf(input)) + createNode(buildContext, listOf(input)) } } } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/avatar/RoomMemberAvatarPreviewNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/avatar/AvatarPreviewNode.kt similarity index 95% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/avatar/RoomMemberAvatarPreviewNode.kt rename to features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/avatar/AvatarPreviewNode.kt index 8d186ae96c..ecd2806b88 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/avatar/RoomMemberAvatarPreviewNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/avatar/AvatarPreviewNode.kt @@ -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, presenterFactory: MediaViewerPresenter.Factory, From 2c6169c6a61e507eaf88b0e9c6dd6ae2baa8fe50 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Dec 2023 15:15:10 +0100 Subject: [PATCH 5/8] changelog --- changelog.d/1918.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/1918.misc diff --git a/changelog.d/1918.misc b/changelog.d/1918.misc new file mode 100644 index 0000000000..d850c133f8 --- /dev/null +++ b/changelog.d/1918.misc @@ -0,0 +1 @@ +Add ability to see the room avatar in the media viewer. From 6e5c973df0d11b630eb8c2cf3c12a77eee7c6385 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Dec 2023 15:22:31 +0100 Subject: [PATCH 6/8] Rename the parameter this it can be a username or a room name. --- .../features/roomdetails/impl/RoomDetailsFlowNode.kt | 8 ++++---- .../android/features/roomdetails/impl/RoomDetailsNode.kt | 6 +++--- .../android/features/roomdetails/impl/RoomDetailsView.kt | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt index adab05262a..2eaab295c4 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt @@ -87,7 +87,7 @@ class RoomDetailsFlowNode @AssistedInject constructor( data class RoomMemberDetails(val roomMemberId: UserId) : NavTarget @Parcelize - data class AvatarPreview(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.AvatarPreview(username, url)) + override fun openAvatarPreview(name: String, url: String) { + backstack.push(NavTarget.AvatarPreview(name, url)) } } createNode(buildContext, listOf(roomDetailsCallback)) @@ -166,7 +166,7 @@ class RoomDetailsFlowNode @AssistedInject constructor( val mimeType = MimeTypes.Images val input = MediaViewerNode.Inputs( mediaInfo = MediaInfo( - name = navTarget.userName, + name = navTarget.name, mimeType = mimeType, formattedFileSize = "", fileExtension = "" diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsNode.kt index f3fa9e2645..c656aa4449 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsNode.kt @@ -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() @@ -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 diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index 042ba2f71e..66455daf90 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -91,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() { From e06f5a68361fe987f24fa15c8f282267e387bc8b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Dec 2023 15:25:08 +0100 Subject: [PATCH 7/8] No need to pass a similar thumbnail source. --- .../android/features/roomdetails/impl/RoomDetailsFlowNode.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt index 2eaab295c4..36de25c270 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt @@ -172,7 +172,7 @@ class RoomDetailsFlowNode @AssistedInject constructor( fileExtension = "" ), mediaSource = MediaSource(url = navTarget.avatarUrl), - thumbnailSource = MediaSource(url = navTarget.avatarUrl), + thumbnailSource = null, canDownload = false, canShare = false, ) From 94858cffb6b159f036e2d52030883ee4d3a17ce4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 14 Dec 2023 15:25:45 +0100 Subject: [PATCH 8/8] Cleanup: Inline val for code clarity / compact. --- .../android/features/messages/impl/MessagesFlowNode.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt index 7957eb2200..cc9ded778b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt @@ -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)