From 7a418918d6916e4d50e54e14c9155b28da45b439 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Sun, 4 Aug 2024 22:24:08 +0100 Subject: [PATCH] ios: blur images of blocked group members (#4573) * ios: blur images of blocked group members * refactor --- .../Shared/Views/Chat/ChatItemInfoView.swift | 2 +- apps/ios/Shared/Views/Chat/ChatView.swift | 2 +- .../Views/Chat/Group/GroupChatInfoView.swift | 2 +- .../Views/Chat/Group/GroupMemberInfoView.swift | 17 ++++++++++++++++- .../Shared/Views/Helpers/ProfileImage.swift | 3 ++- .../Shared/Views/Helpers/ViewModifiers.swift | 4 ++-- apps/ios/SimpleXChat/ImageUtils.swift | 18 +++++++++++++----- 7 files changed, 36 insertions(+), 12 deletions(-) diff --git a/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift b/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift index a46cf03bdf..dc917e7427 100644 --- a/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItemInfoView.swift @@ -440,7 +440,7 @@ struct ChatItemInfoView: View { private func memberDeliveryStatusView(_ member: GroupMember, _ status: GroupSndStatus, _ sentViaProxy: Bool?) -> some View { HStack{ - ProfileImage(imageStr: member.image, size: 30) + MemberProfileImage(member, size: 30) .padding(.trailing, 2) Text(member.chatViewName) .lineLimit(1) diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index 9b770c06fc..9a55060c7d 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -813,7 +813,7 @@ struct ChatView: View { .padding(.trailing, 12) } HStack(alignment: .top, spacing: 8) { - ProfileImage(imageStr: member.memberProfile.image, size: memberImageSize, backgroundColor: theme.colors.background) + MemberProfileImage(member, size: memberImageSize, backgroundColor: theme.colors.background) .onTapGesture { if m.membersLoaded { selectedMember = m.getGroupMember(member.groupMemberId) diff --git a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift index f89009f93f..2b8656bfa4 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift @@ -226,7 +226,7 @@ struct GroupChatInfoView: View { var body: some View { let member = groupMember.wrapped let v = HStack{ - ProfileImage(imageStr: member.image, size: 38) + MemberProfileImage(member, size: 38) .padding(.trailing, 2) // TODO server connection status VStack(alignment: .leading) { diff --git a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift index 12b5bd5a98..5bbaf49d8e 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupMemberInfoView.swift @@ -320,7 +320,7 @@ struct GroupMemberInfoView: View { private func groupMemberInfoHeader(_ mem: GroupMember) -> some View { VStack { - ProfileImage(imageStr: mem.image, size: 192, color: Color(uiColor: .tertiarySystemFill)) + MemberProfileImage(mem, size: 192, color: Color(uiColor: .tertiarySystemFill)) .padding(.top, 12) .padding() if mem.verified { @@ -582,6 +582,21 @@ struct GroupMemberInfoView: View { } } +func MemberProfileImage( + _ mem: GroupMember, + size: CGFloat, + color: Color = Color(uiColor: .tertiarySystemGroupedBackground), + backgroundColor: Color? = nil +) -> some View { + ProfileImage( + imageStr: mem.image, + size: size, + color: color, + backgroundColor: backgroundColor, + blurred: mem.blocked + ) +} + func blockMemberAlert(_ gInfo: GroupInfo, _ mem: GroupMember) -> Alert { Alert( title: Text("Block member?"), diff --git a/apps/ios/Shared/Views/Helpers/ProfileImage.swift b/apps/ios/Shared/Views/Helpers/ProfileImage.swift index 4e6d63ffe0..248504c59b 100644 --- a/apps/ios/Shared/Views/Helpers/ProfileImage.swift +++ b/apps/ios/Shared/Views/Helpers/ProfileImage.swift @@ -16,11 +16,12 @@ struct ProfileImage: View { var size: CGFloat var color = Color(uiColor: .tertiarySystemGroupedBackground) var backgroundColor: Color? = nil + var blurred = false @AppStorage(DEFAULT_PROFILE_IMAGE_CORNER_RADIUS) private var radius = defaultProfileImageCorner var body: some View { if let uiImage = UIImage(base64Encoded: imageStr) { - clipProfileImage(Image(uiImage: uiImage), size: size, radius: radius) + clipProfileImage(Image(uiImage: uiImage), size: size, radius: radius, blurred: blurred) } else { let c = color.asAnotherColorFromSecondaryVariant(theme) Image(systemName: iconName) diff --git a/apps/ios/Shared/Views/Helpers/ViewModifiers.swift b/apps/ios/Shared/Views/Helpers/ViewModifiers.swift index fee0f262cb..c790b9cff2 100644 --- a/apps/ios/Shared/Views/Helpers/ViewModifiers.swift +++ b/apps/ios/Shared/Views/Helpers/ViewModifiers.swift @@ -9,8 +9,8 @@ import SwiftUI extension View { - @ViewBuilder func `if`(_ condition: @autoclosure () -> Bool, transform: (Self) -> Content) -> some View { - if condition() { + @ViewBuilder func `if`(_ condition: Bool, transform: (Self) -> Content) -> some View { + if condition { transform(self) } else { self diff --git a/apps/ios/SimpleXChat/ImageUtils.swift b/apps/ios/SimpleXChat/ImageUtils.swift index ef34c2308e..67218a781e 100644 --- a/apps/ios/SimpleXChat/ImageUtils.swift +++ b/apps/ios/SimpleXChat/ImageUtils.swift @@ -433,17 +433,25 @@ private let squareToCircleRatio = 0.935 private let radiusFactor = (1 - squareToCircleRatio) / 50 -@ViewBuilder public func clipProfileImage(_ img: Image, size: CGFloat, radius: Double) -> some View { - let v = img.resizable() +@ViewBuilder public func clipProfileImage(_ img: Image, size: CGFloat, radius: Double, blurred: Bool = false) -> some View { if radius >= 50 { - v.frame(width: size, height: size).clipShape(Circle()) + blurredFrame(img, size, blurred).clipShape(Circle()) } else if radius <= 0 { let sz = size * squareToCircleRatio - v.frame(width: sz, height: sz).padding((size - sz) / 2) + blurredFrame(img, sz, blurred).padding((size - sz) / 2) } else { let sz = size * (squareToCircleRatio + radius * radiusFactor) - v.frame(width: sz, height: sz) + blurredFrame(img, sz, blurred) .clipShape(RoundedRectangle(cornerRadius: sz * radius / 100, style: .continuous)) .padding((size - sz) / 2) } } + +@ViewBuilder private func blurredFrame(_ img: Image, _ size: CGFloat, _ blurred: Bool) -> some View { + let v = img.resizable().frame(width: size, height: size) + if blurred { + v.blur(radius: size / 4) + } else { + v + } +}