mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Allow focusing the different avatars making up a DM details cluster separately. (#3341)
This commit is contained in:
@@ -26,13 +26,13 @@ struct AvatarHeaderView<Footer: View>: View {
|
||||
|
||||
private let avatarSize: AvatarSize
|
||||
private let mediaProvider: MediaProviderProtocol?
|
||||
private var onAvatarTap: (() -> Void)?
|
||||
private var onAvatarTap: ((URL) -> Void)?
|
||||
@ViewBuilder private var footer: () -> Footer
|
||||
|
||||
init(room: RoomDetails,
|
||||
avatarSize: AvatarSize,
|
||||
mediaProvider: MediaProviderProtocol? = nil,
|
||||
onAvatarTap: (() -> Void)? = nil,
|
||||
onAvatarTap: ((URL) -> Void)? = nil,
|
||||
@ViewBuilder footer: @escaping () -> Footer) {
|
||||
avatarInfo = .room(room.avatar)
|
||||
title = room.name ?? room.id
|
||||
@@ -54,7 +54,7 @@ struct AvatarHeaderView<Footer: View>: View {
|
||||
init(accountOwner: RoomMemberDetails,
|
||||
dmRecipient: RoomMemberDetails,
|
||||
mediaProvider: MediaProviderProtocol? = nil,
|
||||
onAvatarTap: (() -> Void)? = nil,
|
||||
onAvatarTap: ((URL) -> Void)? = nil,
|
||||
@ViewBuilder footer: @escaping () -> Footer) {
|
||||
let dmRecipientProfile = UserProfileProxy(member: dmRecipient)
|
||||
avatarInfo = .room(.heroes([dmRecipientProfile, UserProfileProxy(member: accountOwner)]))
|
||||
@@ -72,7 +72,7 @@ struct AvatarHeaderView<Footer: View>: View {
|
||||
init(member: RoomMemberDetails,
|
||||
avatarSize: AvatarSize,
|
||||
mediaProvider: MediaProviderProtocol? = nil,
|
||||
onAvatarTap: (() -> Void)? = nil,
|
||||
onAvatarTap: ((URL) -> Void)? = nil,
|
||||
@ViewBuilder footer: @escaping () -> Footer) {
|
||||
let profile = UserProfileProxy(member: member)
|
||||
|
||||
@@ -86,7 +86,7 @@ struct AvatarHeaderView<Footer: View>: View {
|
||||
init(user: UserProfileProxy,
|
||||
avatarSize: AvatarSize,
|
||||
mediaProvider: MediaProviderProtocol? = nil,
|
||||
onAvatarTap: (() -> Void)? = nil,
|
||||
onAvatarTap: ((URL) -> Void)? = nil,
|
||||
@ViewBuilder footer: @escaping () -> Footer) {
|
||||
avatarInfo = .user(user)
|
||||
title = user.displayName ?? user.userID
|
||||
@@ -128,24 +128,22 @@ struct AvatarHeaderView<Footer: View>: View {
|
||||
case .room(let roomAvatar):
|
||||
RoomAvatarImage(avatar: roomAvatar,
|
||||
avatarSize: avatarSize,
|
||||
mediaProvider: mediaProvider)
|
||||
mediaProvider: mediaProvider,
|
||||
onAvatarTap: onAvatarTap)
|
||||
|
||||
case .user(let userProfile):
|
||||
LoadableAvatarImage(url: userProfile.avatarURL,
|
||||
name: userProfile.displayName,
|
||||
contentID: userProfile.userID,
|
||||
avatarSize: avatarSize,
|
||||
mediaProvider: mediaProvider)
|
||||
mediaProvider: mediaProvider,
|
||||
onTap: onAvatarTap)
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 8.0) {
|
||||
Button {
|
||||
onAvatarTap?()
|
||||
} label: {
|
||||
avatar
|
||||
}
|
||||
.buttonStyle(.borderless) // Add a button style to stop the whole row being tappable.
|
||||
avatar
|
||||
|
||||
Spacer()
|
||||
.frame(height: 9)
|
||||
|
||||
@@ -13,20 +13,39 @@ struct LoadableAvatarImage: View {
|
||||
private let contentID: String?
|
||||
private let avatarSize: AvatarSize
|
||||
private let mediaProvider: MediaProviderProtocol?
|
||||
private let onTap: ((URL) -> Void)?
|
||||
|
||||
@ScaledMetric private var frameSize: CGFloat
|
||||
|
||||
init(url: URL?, name: String?, contentID: String?, avatarSize: AvatarSize, mediaProvider: MediaProviderProtocol?) {
|
||||
init(url: URL?, name: String?,
|
||||
contentID: String?,
|
||||
avatarSize: AvatarSize,
|
||||
mediaProvider: MediaProviderProtocol?,
|
||||
onTap: ((URL) -> Void)? = nil) {
|
||||
self.url = url
|
||||
self.name = name
|
||||
self.contentID = contentID
|
||||
self.avatarSize = avatarSize
|
||||
self.mediaProvider = mediaProvider
|
||||
self.onTap = onTap
|
||||
|
||||
_frameSize = ScaledMetric(wrappedValue: avatarSize.value)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
if let onTap, let url {
|
||||
Button {
|
||||
onTap(url)
|
||||
} label: {
|
||||
clippedAvatar
|
||||
}
|
||||
.buttonStyle(.borderless) // Add a button style to stop the whole row being tappable.
|
||||
} else {
|
||||
clippedAvatar
|
||||
}
|
||||
}
|
||||
|
||||
private var clippedAvatar: some View {
|
||||
avatar
|
||||
.frame(width: frameSize, height: frameSize)
|
||||
.background(Color.compound.bgCanvasDefault)
|
||||
@@ -34,7 +53,7 @@ struct LoadableAvatarImage: View {
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
var avatar: some View {
|
||||
private var avatar: some View {
|
||||
if let url {
|
||||
LoadableImage(url: url,
|
||||
mediaType: .avatar,
|
||||
|
||||
@@ -25,6 +25,8 @@ struct RoomAvatarImage: View {
|
||||
let avatarSize: AvatarSize
|
||||
let mediaProvider: MediaProviderProtocol?
|
||||
|
||||
private(set) var onAvatarTap: ((URL) -> Void)?
|
||||
|
||||
var body: some View {
|
||||
switch avatar {
|
||||
case .room(let id, let name, let avatarURL):
|
||||
@@ -32,7 +34,8 @@ struct RoomAvatarImage: View {
|
||||
name: name,
|
||||
contentID: id,
|
||||
avatarSize: avatarSize,
|
||||
mediaProvider: mediaProvider)
|
||||
mediaProvider: mediaProvider,
|
||||
onTap: onAvatarTap)
|
||||
case .heroes(let users):
|
||||
// We will expand upon this with more stack sizes in the future.
|
||||
if users.count == 0 {
|
||||
@@ -45,14 +48,16 @@ struct RoomAvatarImage: View {
|
||||
name: users[0].displayName,
|
||||
contentID: users[0].userID,
|
||||
avatarSize: avatarSize,
|
||||
mediaProvider: mediaProvider)
|
||||
mediaProvider: mediaProvider,
|
||||
onTap: onAvatarTap)
|
||||
.scaledFrame(size: clusterSize, alignment: .topTrailing)
|
||||
|
||||
LoadableAvatarImage(url: users[1].avatarURL,
|
||||
name: users[1].displayName,
|
||||
contentID: users[1].userID,
|
||||
avatarSize: avatarSize,
|
||||
mediaProvider: mediaProvider)
|
||||
mediaProvider: mediaProvider,
|
||||
onTap: onAvatarTap)
|
||||
.mask {
|
||||
Rectangle()
|
||||
.fill(Color.white)
|
||||
@@ -74,7 +79,8 @@ struct RoomAvatarImage: View {
|
||||
name: users[0].displayName,
|
||||
contentID: users[0].userID,
|
||||
avatarSize: avatarSize,
|
||||
mediaProvider: mediaProvider)
|
||||
mediaProvider: mediaProvider,
|
||||
onTap: onAvatarTap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user