From afdf5d6c41cd261afecd3edcbe8442ee80bb1b1a Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 11 Feb 2025 17:42:48 +0200 Subject: [PATCH 1/9] Introduce a `UserIdentityProxy` and have it combine upstream methods into an easy to digest `UserIdentityVerificationState`. Use it in a dedicated `VerificationBadge` UI component --- ElementX/Sources/Mocks/ClientProxyMock.swift | 2 +- .../Mocks/Generated/GeneratedMocks.swift | 18 ++- .../Mocks/Generated/SDKGeneratedMocks.swift | 130 ++++++++++++++++++ ...Mock.swift => UserIdentityProxyMock.swift} | 9 +- .../Other/SwiftUI/VerificationBadge.swift | 26 ++++ .../RoomMemberDetailsScreenViewModel.swift | 2 +- .../View/RoomMemberDetailsScreen.swift | 2 +- .../UserProfileScreenViewModel.swift | 2 +- .../View/UserProfileScreen.swift | 2 +- .../Sources/Services/Client/ClientProxy.swift | 8 +- .../Services/Client/ClientProxyProtocol.swift | 2 +- .../Services/Users/UserIdentityProxy.swift | 26 ++++ .../Users/UserIdentityProxyProtocol.swift | 17 +++ 13 files changed, 227 insertions(+), 19 deletions(-) rename ElementX/Sources/Mocks/{SDK/UserIdentitySDKMock.swift => UserIdentityProxyMock.swift} (65%) create mode 100644 ElementX/Sources/Other/SwiftUI/VerificationBadge.swift create mode 100644 ElementX/Sources/Services/Users/UserIdentityProxy.swift create mode 100644 ElementX/Sources/Services/Users/UserIdentityProxyProtocol.swift diff --git a/ElementX/Sources/Mocks/ClientProxyMock.swift b/ElementX/Sources/Mocks/ClientProxyMock.swift index 5c31e02509..cc96967d09 100644 --- a/ElementX/Sources/Mocks/ClientProxyMock.swift +++ b/ElementX/Sources/Mocks/ClientProxyMock.swift @@ -95,6 +95,6 @@ extension ClientProxyMock { return await .joined(JoinedRoomProxyMock(.init(id: room.id, name: room.name))) } - userIdentityForReturnValue = .success(UserIdentitySDKMock(configuration: .init())) + userIdentityForReturnValue = .success(UserIdentityProxyMock(configuration: .init())) } } diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index 681b745c7f..35403c618c 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -4860,13 +4860,13 @@ class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable { var userIdentityForReceivedUserID: String? var userIdentityForReceivedInvocations: [String] = [] - var userIdentityForUnderlyingReturnValue: Result! - var userIdentityForReturnValue: Result! { + var userIdentityForUnderlyingReturnValue: Result! + var userIdentityForReturnValue: Result! { get { if Thread.isMainThread { return userIdentityForUnderlyingReturnValue } else { - var returnValue: Result? = nil + var returnValue: Result? = nil DispatchQueue.main.sync { returnValue = userIdentityForUnderlyingReturnValue } @@ -4884,9 +4884,9 @@ class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable { } } } - var userIdentityForClosure: ((String) async -> Result)? + var userIdentityForClosure: ((String) async -> Result)? - func userIdentity(for userID: String) async -> Result { + func userIdentity(for userID: String) async -> Result { userIdentityForCallsCount += 1 userIdentityForReceivedUserID = userID DispatchQueue.main.async { @@ -16511,6 +16511,14 @@ class UserDiscoveryServiceMock: UserDiscoveryServiceProtocol, @unchecked Sendabl } } } +class UserIdentityProxyMock: UserIdentityProxyProtocol, @unchecked Sendable { + var verificationState: UserIdentityVerificationState { + get { return underlyingVerificationState } + set(value) { underlyingVerificationState = value } + } + var underlyingVerificationState: UserIdentityVerificationState! + +} class UserIndicatorControllerMock: UserIndicatorControllerProtocol, @unchecked Sendable { var window: UIWindow? var alertInfo: AlertInfo? diff --git a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift index 833c4ae4cd..836b351b72 100644 --- a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift @@ -22876,6 +22876,71 @@ open class UserIdentitySDKMock: MatrixRustSDK.UserIdentity, @unchecked Sendable fileprivate var pointer: UnsafeMutableRawPointer! + //MARK: - hasVerificationViolation + + var hasVerificationViolationUnderlyingCallsCount = 0 + open var hasVerificationViolationCallsCount: Int { + get { + if Thread.isMainThread { + return hasVerificationViolationUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = hasVerificationViolationUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + hasVerificationViolationUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + hasVerificationViolationUnderlyingCallsCount = newValue + } + } + } + } + open var hasVerificationViolationCalled: Bool { + return hasVerificationViolationCallsCount > 0 + } + + var hasVerificationViolationUnderlyingReturnValue: Bool! + open var hasVerificationViolationReturnValue: Bool! { + get { + if Thread.isMainThread { + return hasVerificationViolationUnderlyingReturnValue + } else { + var returnValue: Bool? = nil + DispatchQueue.main.sync { + returnValue = hasVerificationViolationUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + hasVerificationViolationUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + hasVerificationViolationUnderlyingReturnValue = newValue + } + } + } + } + open var hasVerificationViolationClosure: (() -> Bool)? + + open override func hasVerificationViolation() -> Bool { + hasVerificationViolationCallsCount += 1 + if let hasVerificationViolationClosure = hasVerificationViolationClosure { + return hasVerificationViolationClosure() + } else { + return hasVerificationViolationReturnValue + } + } + //MARK: - isVerified var isVerifiedUnderlyingCallsCount = 0 @@ -23046,6 +23111,71 @@ open class UserIdentitySDKMock: MatrixRustSDK.UserIdentity, @unchecked Sendable try await pinClosure?() } + //MARK: - wasPreviouslyVerified + + var wasPreviouslyVerifiedUnderlyingCallsCount = 0 + open var wasPreviouslyVerifiedCallsCount: Int { + get { + if Thread.isMainThread { + return wasPreviouslyVerifiedUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = wasPreviouslyVerifiedUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + wasPreviouslyVerifiedUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + wasPreviouslyVerifiedUnderlyingCallsCount = newValue + } + } + } + } + open var wasPreviouslyVerifiedCalled: Bool { + return wasPreviouslyVerifiedCallsCount > 0 + } + + var wasPreviouslyVerifiedUnderlyingReturnValue: Bool! + open var wasPreviouslyVerifiedReturnValue: Bool! { + get { + if Thread.isMainThread { + return wasPreviouslyVerifiedUnderlyingReturnValue + } else { + var returnValue: Bool? = nil + DispatchQueue.main.sync { + returnValue = wasPreviouslyVerifiedUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + wasPreviouslyVerifiedUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + wasPreviouslyVerifiedUnderlyingReturnValue = newValue + } + } + } + } + open var wasPreviouslyVerifiedClosure: (() -> Bool)? + + open override func wasPreviouslyVerified() -> Bool { + wasPreviouslyVerifiedCallsCount += 1 + if let wasPreviouslyVerifiedClosure = wasPreviouslyVerifiedClosure { + return wasPreviouslyVerifiedClosure() + } else { + return wasPreviouslyVerifiedReturnValue + } + } + //MARK: - withdrawVerification open var withdrawVerificationThrowableError: Error? diff --git a/ElementX/Sources/Mocks/SDK/UserIdentitySDKMock.swift b/ElementX/Sources/Mocks/UserIdentityProxyMock.swift similarity index 65% rename from ElementX/Sources/Mocks/SDK/UserIdentitySDKMock.swift rename to ElementX/Sources/Mocks/UserIdentityProxyMock.swift index c1b8c79484..7a59583821 100644 --- a/ElementX/Sources/Mocks/SDK/UserIdentitySDKMock.swift +++ b/ElementX/Sources/Mocks/UserIdentityProxyMock.swift @@ -1,14 +1,11 @@ // -// Copyright 2024 New Vector Ltd. +// Copyright 2025 New Vector Ltd. // // SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial // Please see LICENSE files in the repository root for full details. // -import Foundation -import MatrixRustSDK - -extension UserIdentitySDKMock { +extension UserIdentityProxyMock { struct Configuration { var isVerified = false } @@ -16,6 +13,6 @@ extension UserIdentitySDKMock { convenience init(configuration: Configuration) { self.init() - isVerifiedReturnValue = configuration.isVerified + underlyingVerificationState = configuration.isVerified ? .verified : .notVerified } } diff --git a/ElementX/Sources/Other/SwiftUI/VerificationBadge.swift b/ElementX/Sources/Other/SwiftUI/VerificationBadge.swift new file mode 100644 index 0000000000..d110cd3aa7 --- /dev/null +++ b/ElementX/Sources/Other/SwiftUI/VerificationBadge.swift @@ -0,0 +1,26 @@ +// +// Copyright 2025 New Vector Ltd. +// +// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +// Please see LICENSE files in the repository root for full details. +// + +import Compound +import SwiftUI + +struct VerificationBadge: View { + let verificationState: UserIdentityVerificationState + + var body: some View { + switch verificationState { + case .verified: + CompoundIcon(\.verified, size: .small, relativeTo: .compound.bodyMD) + .foregroundStyle(.compound.iconSuccessPrimary) + case .verificationViolation: + CompoundIcon(\.infoSolid, size: .small, relativeTo: .compound.bodyMD) + .foregroundStyle(.compound.iconCriticalPrimary) + case .notVerified: + EmptyView() + } + } +} diff --git a/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenViewModel.swift b/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenViewModel.swift index b5cadba6c6..96ebbca5f7 100644 --- a/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenViewModel.swift @@ -106,7 +106,7 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro } if case let .success(.some(identity)) = await identityResult { - state.isVerified = identity.isVerified() + state.isVerified = identity.verificationState == .verified } else { MXLog.error("Failed to find the member's identity.") } diff --git a/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift b/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift index 90d40b7152..f17948ccb0 100644 --- a/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift +++ b/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift @@ -175,7 +175,7 @@ struct RoomMemberDetailsScreen_Previews: PreviewProvider, TestablePreview { clientProxyMock.userIdentityForClosure = { userID in let isVerified = userID == RoomMemberProxyMock.mockDan.userID - return .success(UserIdentitySDKMock(configuration: .init(isVerified: isVerified))) + return .success(UserIdentityProxyMock(configuration: .init(isVerified: isVerified))) } // to avoid mock the call state for the account owner test case if member.userID != RoomMemberProxyMock.mockMe.userID { diff --git a/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenViewModel.swift b/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenViewModel.swift index c64670c1ce..8ea0203b5f 100644 --- a/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenViewModel.swift +++ b/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenViewModel.swift @@ -95,7 +95,7 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr } if case let .success(.some(identity)) = await identityResult { - state.isVerified = identity.isVerified() + state.isVerified = identity.verificationState == .verified } else { MXLog.error("Failed to find the user's identity.") } diff --git a/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift b/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift index 1fac8bc63b..c0c00dcca0 100644 --- a/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift +++ b/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift @@ -139,7 +139,7 @@ struct UserProfileScreen_Previews: PreviewProvider, TestablePreview { let clientProxyMock = ClientProxyMock(.init()) clientProxyMock.userIdentityForClosure = { userID in let isVerified = userID == RoomMemberProxyMock.mockDan.userID - return .success(UserIdentitySDKMock(configuration: .init(isVerified: isVerified))) + return .success(UserIdentityProxyMock(configuration: .init(isVerified: isVerified))) } if userID != RoomMemberProxyMock.mockMe.userID { clientProxyMock.directRoomForUserIDReturnValue = .success("roomID") diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 8efdfefd12..99352d2533 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -1018,9 +1018,13 @@ class ClientProxy: ClientProxyProtocol { } } - func userIdentity(for userID: String) async -> Result { + func userIdentity(for userID: String) async -> Result { do { - return try await .success(client.encryption().userIdentity(userId: userID)) + guard let userIdentity = try await client.encryption().userIdentity(userId: userID) else { + return .success(nil) + } + + return .success(UserIdentityProxy(userIdentity: userIdentity)) } catch { MXLog.error("Failed retrieving user identity: \(error)") return .failure(.sdkError(error)) diff --git a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift index 2fce3d68a1..acbe47284b 100644 --- a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift +++ b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift @@ -191,5 +191,5 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol { func withdrawUserIdentityVerification(_ userID: String) async -> Result func resetIdentity() async -> Result - func userIdentity(for userID: String) async -> Result + func userIdentity(for userID: String) async -> Result } diff --git a/ElementX/Sources/Services/Users/UserIdentityProxy.swift b/ElementX/Sources/Services/Users/UserIdentityProxy.swift new file mode 100644 index 0000000000..072c1920bf --- /dev/null +++ b/ElementX/Sources/Services/Users/UserIdentityProxy.swift @@ -0,0 +1,26 @@ +// +// Copyright 2025 New Vector Ltd. +// +// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +// Please see LICENSE files in the repository root for full details. +// + +import MatrixRustSDK + +class UserIdentityProxy: UserIdentityProxyProtocol { + private let userIdentity: UserIdentity + + init(userIdentity: UserIdentity) { + self.userIdentity = userIdentity + } + + var verificationState: UserIdentityVerificationState { + if userIdentity.hasVerificationViolation() { + return .verificationViolation + } else if userIdentity.isVerified() { + return .verified + } + + return .notVerified + } +} diff --git a/ElementX/Sources/Services/Users/UserIdentityProxyProtocol.swift b/ElementX/Sources/Services/Users/UserIdentityProxyProtocol.swift new file mode 100644 index 0000000000..03f8a0406a --- /dev/null +++ b/ElementX/Sources/Services/Users/UserIdentityProxyProtocol.swift @@ -0,0 +1,17 @@ +// +// Copyright 2025 New Vector Ltd. +// +// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +// Please see LICENSE files in the repository root for full details. +// + +enum UserIdentityVerificationState { + case notVerified + case verified + case verificationViolation +} + +// sourcery: AutoMockable +protocol UserIdentityProxyProtocol { + var verificationState: UserIdentityVerificationState { get } +} From bde1cb9a5f1ee8cd0cacc83285823ac03132d27c Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 11 Feb 2025 17:45:47 +0200 Subject: [PATCH 2/9] Show a DMs counterpart verification state in the room header --- .../Other/SwiftUI/Views/RoomHeaderView.swift | 41 ++++++++++++------- .../Screens/RoomScreen/RoomScreenModels.swift | 1 + .../RoomScreen/RoomScreenViewModel.swift | 15 +++++++ .../Screens/RoomScreen/View/RoomScreen.swift | 1 + 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift b/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift index 377b4719d3..cdd5d6e37d 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift @@ -12,17 +12,25 @@ import SwiftUI struct RoomHeaderView: View { let roomName: String let roomAvatar: RoomAvatar + var counterpartVerificationState: UserIdentityVerificationState? let mediaProvider: MediaProviderProtocol? var body: some View { - HStack(spacing: 12) { + HStack(spacing: 8) { avatarImage .accessibilityHidden(true) - Text(roomName) - .lineLimit(1) - .font(.compound.bodyLGSemibold) - .accessibilityIdentifier(A11yIdentifiers.roomScreen.name) + + HStack(spacing: 4) { + Text(roomName) + .lineLimit(1) + .font(.compound.bodyLGSemibold) + .accessibilityIdentifier(A11yIdentifiers.roomScreen.name) + + if let counterpartVerificationState { + VerificationBadge(verificationState: counterpartVerificationState) + } + } } // Take up as much space as possible, with a leading alignment for use in the principal toolbar position. .frame(idealWidth: .greatestFiniteMagnitude, maxWidth: .infinity, alignment: .leading) @@ -38,20 +46,23 @@ struct RoomHeaderView: View { struct RoomHeaderView_Previews: PreviewProvider, TestablePreview { static var previews: some View { + VStack(spacing: 8) { + makeHeader(avatarURL: nil, verificationState: .notVerified) + makeHeader(avatarURL: .mockMXCAvatar, verificationState: .notVerified) + makeHeader(avatarURL: .mockMXCAvatar, verificationState: .verified) + makeHeader(avatarURL: .mockMXCAvatar, verificationState: .verificationViolation) + } + .previewLayout(.sizeThatFits) + } + + static func makeHeader(avatarURL: URL?, + verificationState: UserIdentityVerificationState) -> some View { RoomHeaderView(roomName: "Some Room name", roomAvatar: .room(id: "1", name: "Some Room Name", - avatarURL: .mockMXCAvatar), - mediaProvider: MediaProviderMock(configuration: .init())) - .previewLayout(.sizeThatFits) - .padding() - - RoomHeaderView(roomName: "Some Room name", - roomAvatar: .room(id: "1", - name: "Some Room Name", - avatarURL: nil), + avatarURL: avatarURL), + counterpartVerificationState: verificationState, mediaProvider: MediaProviderMock(configuration: .init())) - .previewLayout(.sizeThatFits) .padding() } } diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift index 7943cbc2fa..f1a5c5820c 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift @@ -31,6 +31,7 @@ enum RoomScreenViewAction { struct RoomScreenViewState: BindableState { var roomTitle = "" var roomAvatar: RoomAvatar + var counterpartVerificationState: UserIdentityVerificationState? var lastScrollDirection: ScrollDirection? // This is used to control the banner diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index 68a9519ba2..ac1438478f 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -77,6 +77,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol Task { await handleRoomInfoUpdate(roomProxy.infoPublisher.value) + + await updateVerificationBadge() } setupSubscriptions(ongoingCallRoomIDPublisher: ongoingCallRoomIDPublisher) @@ -182,6 +184,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol } await self?.processIdentityStatusChanges(changes) + await self?.updateVerificationBadge() } } .store(in: &cancellables) @@ -262,6 +265,18 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol } } + private func updateVerificationBadge() async { + guard roomProxy.isDirectOneToOneRoom, + let dmRecipient = roomProxy.membersPublisher.value.first(where: { $0.userID != roomProxy.ownUserID }), + case let .success(userIdentity) = await clientProxy.userIdentity(for: dmRecipient.userID), + let userIdentity else { + state.counterpartVerificationState = .notVerified + return + } + + state.counterpartVerificationState = userIdentity.verificationState + } + private func resolveIdentityPinningViolation(_ userID: String) async { defer { hideLoadingIndicator() diff --git a/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift b/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift index 37b1f1fef8..ecd5139d86 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift @@ -204,6 +204,7 @@ struct RoomScreen: View { ToolbarItem(placement: .principal) { RoomHeaderView(roomName: roomContext.viewState.roomTitle, roomAvatar: roomContext.viewState.roomAvatar, + counterpartVerificationState: roomContext.viewState.counterpartVerificationState, mediaProvider: roomContext.mediaProvider) // Using a button stops it from getting truncated in the navigation bar .contentShape(.rect) From 8b8969ae4d448db62c5d1c0cb24bcc3d6d6e5efc Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 11 Feb 2025 17:54:07 +0200 Subject: [PATCH 3/9] Show a warning on the room details `People` entry when there are identity verification state violations on any of the members. --- .../RoomDetailsScreenModels.swift | 3 +++ .../RoomDetailsScreenViewModel.swift | 24 ++++++++++++++++++ .../View/RoomDetailsScreen.swift | 25 +++++++++++++------ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift index 1b71fdc9a0..f7bdc54dc1 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenModels.swift @@ -39,7 +39,10 @@ struct RoomDetailsScreenViewState: BindableState { var topic: AttributedString? var topicSummary: AttributedString? + var joinedMembersCount: Int + var hasMemberIdentityVerificationStateViolations = false + var isProcessingIgnoreRequest = false var canInviteUsers = false var canEditRoomName = false diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift index 2286754a3e..33ac1c35c9 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenViewModel.swift @@ -200,6 +200,12 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr .throttle(for: .milliseconds(100), scheduler: DispatchQueue.main, latest: true) .weakAssign(to: \.state.knockRequestsCount, on: self) .store(in: &cancellables) + + roomProxy.membersPublisher.combineLatest(roomProxy.identityStatusChangesPublisher) + .sink { _ in + Task { await self.updateMemberIdentityVerificationStates() } + } + .store(in: &cancellables) } private func updateRoomInfo(_ roomInfo: RoomInfoProxy) { @@ -239,6 +245,24 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr await roomProxy.updateMembers() } + private func updateMemberIdentityVerificationStates() async { + guard roomProxy.isEncrypted else { + // We don't care about identity statuses on non-encrypted rooms + return + } + + for member in roomProxy.membersPublisher.value { + if case let .success(identity) = await clientProxy.userIdentity(for: member.userID) { + if identity?.verificationState == .verificationViolation { + state.hasMemberIdentityVerificationStateViolations = true + return + } + } + } + + state.hasMemberIdentityVerificationStateViolations = false + } + private func updatePowerLevelPermissions() async { state.canEditRoomName = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomName).get()) == true state.canEditRoomTopic = await (try? roomProxy.canUser(userID: roomProxy.ownUserID, sendStateEvent: .roomTopic).get()) == true diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift b/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift index 5d169bdd8d..f4e6848606 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/View/RoomDetailsScreen.swift @@ -198,14 +198,23 @@ struct RoomDetailsScreen: View { private var peopleSection: some View { Section { - ListRow(label: .default(title: L10n.commonPeople, - icon: \.user), - details: .title(String(context.viewState.joinedMembersCount)), - kind: .navigationLink { - context.send(viewAction: .processTapPeople) - }) - .accessibilityIdentifier(A11yIdentifiers.roomDetailsScreen.people) - + if context.viewState.hasMemberIdentityVerificationStateViolations { + ListRow(label: .default(title: L10n.commonPeople, icon: \.user), + details: .icon(CompoundIcon(\.infoSolid).foregroundStyle(.compound.iconCriticalPrimary)), + kind: .navigationLink { + context.send(viewAction: .processTapPeople) + }) + .accessibilityIdentifier(A11yIdentifiers.roomDetailsScreen.people) + + } else { + ListRow(label: .default(title: L10n.commonPeople, icon: \.user), + details: .title(String(context.viewState.joinedMembersCount)), + kind: .navigationLink { + context.send(viewAction: .processTapPeople) + }) + .accessibilityIdentifier(A11yIdentifiers.roomDetailsScreen.people) + } + if context.viewState.canSeeKnockingRequests { ListRow(label: .default(title: L10n.screenRoomDetailsRequestsToJoinTitle, icon: \.askToJoin), From ea41a408ad314a4cfa9e6067f0084af6fccbc20f Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 12 Feb 2025 08:51:38 +0200 Subject: [PATCH 4/9] Bump the RustSDK to v25.02.11 --- ElementX.xcodeproj/project.pbxproj | 22 ++++++++++++++----- .../xcshareddata/swiftpm/Package.resolved | 4 ++-- project.yml | 2 +- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 1af330f5f6..cf1ba8eb37 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -106,6 +106,7 @@ 126CBCF5B0145FA1377C1316 /* Tracing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83B574805B9812C111D6215D /* Tracing.swift */; }; 126EE01D8BEAEF26105D83C5 /* RoomDetailsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1A5FEF17ED7E6176D922D4F /* RoomDetailsScreen.swift */; }; 128FFD8A3D85845F9A927F47 /* PollRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF8548D48512127CCC17C520 /* PollRoomTimelineView.swift */; }; + 12AF926E783E40BFB32A2D84 /* UserIdentityProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8536B40F578BA7FDB23D97B1 /* UserIdentityProxyMock.swift */; }; 12C867E85E6D12EEDFD0B127 /* CustomStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C4762F8D6112E43117DB2F /* CustomStringConvertible.swift */; }; 12CCA59536EDD99A3272CF77 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC3F82523D6F48B926D6AF68 /* AppSettings.swift */; }; 12CD8B5CC30A05061228BF9E /* TimelineItemMenuActionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9E6065FC6BC4A1B4C629E08 /* TimelineItemMenuActionProvider.swift */; }; @@ -188,6 +189,7 @@ 238D561CA231339C6D4D06F3 /* ClientBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A1C33355FFB0F0953C35036 /* ClientBuilder.swift */; }; 241CDEFE23819867D9B39066 /* RoomChangePermissionsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE75941583A033A9EDC9FE0 /* RoomChangePermissionsScreenViewModel.swift */; }; 244407B18B2F2D6466BA5961 /* RoomChangeRolesScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82DFA1B7B088D033E0794B82 /* RoomChangeRolesScreenCoordinator.swift */; }; + 2447FADEF13225BB6227B977 /* VerificationBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1D97BAF04AA150C0EF03021 /* VerificationBadge.swift */; }; 244CB93DD7390379D905AFA8 /* DeactivateAccountScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E49D10BFA7E4D70A947888C /* DeactivateAccountScreen.swift */; }; 24A1BBADAC43DC3F3A7347DA /* AnalyticsPromptScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = E53BFB7E4F329621C844E8C3 /* AnalyticsPromptScreen.swift */; }; 24A75F72EEB7561B82D726FD /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2141693488CE5446BB391964 /* Date.swift */; }; @@ -401,6 +403,7 @@ 4E4EF97B9F9CEFAC726BA72F /* TimelineProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62EACAFB3F3E017060F9F1C5 /* TimelineProviderMock.swift */; }; 4E8A2A2CFEB212F14E49E1A1 /* AppLockSetupSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5484457C81B325660901B161 /* AppLockSetupSettingsScreen.swift */; }; 4E945AD6862C403F74E57755 /* RoomTimelineItemFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 105B2A8426404EF66F00CFDB /* RoomTimelineItemFactory.swift */; }; + 4E9782D683660463804C2DC3 /* UserIdentityProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F793C422BDACE0C60C774F4 /* UserIdentityProxyProtocol.swift */; }; 4EA1CE0E88EA68E862FF0EA2 /* NotificationSettingsEditScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B564D748B67A156F413CD97 /* NotificationSettingsEditScreenModels.swift */; }; 4EAC427267424192964B16B3 /* AppSettingsHook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13BE9781699FB510E9263192 /* AppSettingsHook.swift */; }; 4ED764A24F2A715C25CF07F1 /* TimelineMediaPreviewFileExportPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30856520F3263D0E195710D7 /* TimelineMediaPreviewFileExportPicker.swift */; }; @@ -619,6 +622,7 @@ 7A0D335D38ECA095A575B4F7 /* TimelineStyler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DB0E533508094156D8024C3 /* TimelineStyler.swift */; }; 7A170A5A4A352954BB2A1B96 /* AuthenticationStartScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24E8C8817F59BEC7E358EB78 /* AuthenticationStartScreen.swift */; }; 7A25D6926A2C01DB8D0D67A5 /* BadgeLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A028783CFFF861C5E44FFB1 /* BadgeLabel.swift */; }; + 7A495A5F3E5522DD7928CF8F /* UserIdentityProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964093C7CA8823CAB7FFD88E /* UserIdentityProxy.swift */; }; 7A642EE5F1ADC5D520F21924 /* MediaProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85EB16E7FE59A947CA441531 /* MediaProviderProtocol.swift */; }; 7A71AEF419904209BB8C2833 /* UserAgentBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F2529D434C750ED78ADF1ED /* UserAgentBuilder.swift */; }; 7A8B264506D3DDABC01B4EEB /* AppMediator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53AC78E49A297AC1D72A7CF /* AppMediator.swift */; }; @@ -993,7 +997,6 @@ C76892321558E75101E68ED6 /* ReadableFrameModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */; }; C7774720A4B2E34693E3227C /* RoomNotificationSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8896CDD20CA2D87EA3B848A1 /* RoomNotificationSettingsScreen.swift */; }; C7ABEBECDC513F7887DACF66 /* ProgressMaskModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68010886142843705E342645 /* ProgressMaskModifier.swift */; }; - C7B07EBA0F12B5912DA9BB97 /* UserIdentitySDKMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8DE9D0D480D087D0F676B52 /* UserIdentitySDKMock.swift */; }; C7F20DBF873CC72FB482E326 /* test_rotated_image.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 723B055A57857BFF0F18D9CB /* test_rotated_image.jpg */; }; C80E06ED97CE52704A46C148 /* ClientBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A1C33355FFB0F0953C35036 /* ClientBuilder.swift */; }; C85C7A201E4CFDA477ACEBEB /* AppLockSetupSettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8610C1D21565C950BCA6A454 /* AppLockSetupSettingsScreenViewModelProtocol.swift */; }; @@ -1414,6 +1417,7 @@ 0F5567A7EF6F2AB9473236F6 /* DocumentPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentPicker.swift; sourceTree = ""; }; 0F569CFB77E0D40BD82203D9 /* AuthenticationClientBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationClientBuilder.swift; sourceTree = ""; }; 0F64447FF544298A6A3BEF85 /* NotificationSettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenModels.swift; sourceTree = ""; }; + 0F793C422BDACE0C60C774F4 /* UserIdentityProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIdentityProxyProtocol.swift; sourceTree = ""; }; 0FA60F848D1C14F873F9621A /* RoomMemberDetailsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenCoordinator.swift; sourceTree = ""; }; 105429F29096729EDD3152CF /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/SAS.strings; sourceTree = ""; }; 1059E2AE7878CF7820592637 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; @@ -1967,6 +1971,7 @@ 8512B82404B1751D0BCC82D2 /* MediaEventsTimelineScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaEventsTimelineScreenCoordinator.swift; sourceTree = ""; }; 85149F56BA333619900E2410 /* UserDetailsEditScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDetailsEditScreenViewModelProtocol.swift; sourceTree = ""; }; 851B95BB98649B8E773D6790 /* AppLockService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockService.swift; sourceTree = ""; }; + 8536B40F578BA7FDB23D97B1 /* UserIdentityProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIdentityProxyMock.swift; sourceTree = ""; }; 8544F7058D31DBEB8DBFF0F5 /* NotificationSettingsEditScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsEditScreenViewModelTests.swift; sourceTree = ""; }; 854BCEAF2A832176FAACD2CB /* SplashScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreenCoordinator.swift; sourceTree = ""; }; 85666E40F7E817809B4FD787 /* ComposerToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerToolbar.swift; sourceTree = ""; }; @@ -2047,6 +2052,7 @@ 955336CBD5ED73C792D1F580 /* EncryptionAuthenticity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionAuthenticity.swift; sourceTree = ""; }; 95A2E4BD7C0CAD25EF924A4C /* GeneratedPreviewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneratedPreviewTests.swift; sourceTree = ""; }; 95BAC0F6C9644336E9567EE6 /* NSRegularExpresion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSRegularExpresion.swift; sourceTree = ""; }; + 964093C7CA8823CAB7FFD88E /* UserIdentityProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIdentityProxy.swift; sourceTree = ""; }; 969694F67E844FCA51F7E051 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/InfoPlist.strings; sourceTree = ""; }; 96C4762F8D6112E43117DB2F /* CustomStringConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomStringConvertible.swift; sourceTree = ""; }; 96CE9D6642DD487D8CC90C9C /* landscape_test_image.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = landscape_test_image.jpg; sourceTree = ""; }; @@ -2340,6 +2346,7 @@ D196116D2DD3F2757D45FCB7 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/SAS.strings; sourceTree = ""; }; D1BC84BA0AF11C2128D58ABD /* Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Common.swift; sourceTree = ""; }; D1D8479BB704B7EF696F8ABE /* RoomPollsHistoryScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPollsHistoryScreenCoordinator.swift; sourceTree = ""; }; + D1D97BAF04AA150C0EF03021 /* VerificationBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerificationBadge.swift; sourceTree = ""; }; D263254AFE5B7993FFBBF324 /* NSE.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NSE.entitlements; sourceTree = ""; }; D26813CCE39221FE30BF22CD /* PlatformViewVersionPredicate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformViewVersionPredicate.swift; sourceTree = ""; }; D28F7A6CEEA4A2815B0F0F55 /* SettingsFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsFlowCoordinator.swift; sourceTree = ""; }; @@ -2444,7 +2451,6 @@ E8A1F98AE670377B20679FF5 /* MediaPlayerProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPlayerProvider.swift; sourceTree = ""; }; E8AE4B3273BA189FDCD4055C /* UserIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicator.swift; sourceTree = ""; }; E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIFont+AttributedStringBuilder.m"; sourceTree = ""; }; - E8DE9D0D480D087D0F676B52 /* UserIdentitySDKMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIdentitySDKMock.swift; sourceTree = ""; }; E96ED747FF90332EA1333C22 /* RoomTimelineItemFixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemFixtures.swift; sourceTree = ""; }; E992D7B8BE54B2AB454613AF /* XCUIElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCUIElement.swift; sourceTree = ""; }; E9A3D3CFA199FA7897364547 /* CallInviteRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallInviteRoomTimelineItem.swift; sourceTree = ""; }; @@ -2707,6 +2713,7 @@ children = ( 693E16574C6F7F9FA1015A8C /* Search.swift */, 832397B5C3D00A4BF52C5F0B /* ShouldScrollOnKeyboardDidShow.swift */, + D1D97BAF04AA150C0EF03021 /* VerificationBadge.swift */, E2DA161C142B7AB8CC40F752 /* Animation */, CE2FBFD64A89F5DBE4EB30DB /* Layout */, E6E1D07163F8752D62DA4A93 /* Styles */, @@ -3215,6 +3222,7 @@ B0F5CC38803B8382D2C63222 /* TimelineControllerFactoryMock.swift */, 62EACAFB3F3E017060F9F1C5 /* TimelineProviderMock.swift */, 17A8AA0DFA06012A9DAB951E /* TimelineProxyMock.swift */, + 8536B40F578BA7FDB23D97B1 /* UserIdentityProxyMock.swift */, 7893780A1FD6E3F38B3E9049 /* UserIndicatorControllerMock.swift */, AAD01F7FC2BBAC7351948595 /* UserProfile+Mock.swift */, F4469F6AE311BDC439B3A5EC /* UserSessionMock.swift */, @@ -5652,6 +5660,8 @@ D071F86CD47582B9196C9D16 /* UserDiscoverySection.swift */, 65AAD845E53B0C8B5E0812C2 /* UserDiscoveryService.swift */, 7F615A00DB223FF3280204D2 /* UserDiscoveryServiceProtocol.swift */, + 964093C7CA8823CAB7FFD88E /* UserIdentityProxy.swift */, + 0F793C422BDACE0C60C774F4 /* UserIdentityProxyProtocol.swift */, 51C454AE59914B551A6D02C0 /* UserProfileProxy.swift */, ); path = Users; @@ -5717,7 +5727,6 @@ children = ( 8EAF4A49F3ACD8BB8B0D2371 /* ClientSDKMock.swift */, 5EFB1D29B0870AFB6A56E9B8 /* IdentityResetHandleSDKMock.swift */, - E8DE9D0D480D087D0F676B52 /* UserIdentitySDKMock.swift */, ); path = SDK; sourceTree = ""; @@ -7624,7 +7633,9 @@ 828EA5009557C2B9DCD4CA0F /* UserDiscoverySection.swift in Sources */, 044DD8F80231BC30570F7965 /* UserDiscoveryService.swift in Sources */, 1C409A26A99F0371C47AFA51 /* UserDiscoveryServiceProtocol.swift in Sources */, - C7B07EBA0F12B5912DA9BB97 /* UserIdentitySDKMock.swift in Sources */, + 7A495A5F3E5522DD7928CF8F /* UserIdentityProxy.swift in Sources */, + 12AF926E783E40BFB32A2D84 /* UserIdentityProxyMock.swift in Sources */, + 4E9782D683660463804C2DC3 /* UserIdentityProxyProtocol.swift in Sources */, 988BA75A182738150894A23F /* UserIndicator.swift in Sources */, C4E0D03DF88242697545A9B7 /* UserIndicatorController.swift in Sources */, 3467FEE8210D301FF1B77001 /* UserIndicatorControllerMock.swift in Sources */, @@ -7651,6 +7662,7 @@ 7E91BAC17963ED41208F489B /* UserSessionStore.swift in Sources */, 79D57E9AE03A2DC689D14EA2 /* UserSessionStoreMock.swift in Sources */, AC69B6DF15FC451AB2945036 /* UserSessionStoreProtocol.swift in Sources */, + 2447FADEF13225BB6227B977 /* VerificationBadge.swift in Sources */, 5C33976A720B64094CBC56B1 /* VideoMediaEventsTimelineView.swift in Sources */, F07D88421A9BC4D03D4A5055 /* VideoRoomTimelineItem.swift in Sources */, 1A83DD22F3E6F76B13B6E2F9 /* VideoRoomTimelineItemContent.swift in Sources */, @@ -8509,7 +8521,7 @@ repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift"; requirement = { kind = exactVersion; - version = 25.02.07; + version = 25.02.11; }; }; 701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = { diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index f3d95ed8d0..b3da9489d2 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -149,8 +149,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/element-hq/matrix-rust-components-swift", "state" : { - "revision" : "bc819f09ac66bbe1adc2fde2afeb7ab023d1b909", - "version" : "25.2.7" + "revision" : "cc010fc6971370d1df2c0eb67cc5cfd577465b62", + "version" : "25.2.11" } }, { diff --git a/project.yml b/project.yml index 9c9d6db067..724458aa97 100644 --- a/project.yml +++ b/project.yml @@ -61,7 +61,7 @@ packages: # Element/Matrix dependencies MatrixRustSDK: url: https://github.com/element-hq/matrix-rust-components-swift - exactVersion: 25.02.07 + exactVersion: 25.02.11 # path: ../matrix-rust-sdk Compound: url: https://github.com/element-hq/compound-ios From a21aa93c414ffc344f2f8a53feb028d3c4f85cba Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 12 Feb 2025 15:02:21 +0200 Subject: [PATCH 5/9] Show verification badges in the room member list --- .../RoomFlowCoordinator.swift | 3 +- .../Sources/Mocks/UserIdentityProxyMock.swift | 4 +- .../View/RoomMemberDetailsScreen.swift | 12 +++- .../RoomMembersListScreenCoordinator.swift | 6 +- .../RoomMembersListScreenModels.swift | 29 ++++---- .../RoomMembersListScreenViewModel.swift | 61 +++++++++------- .../RoomMembersListManageMemberSheet.swift | 1 + .../View/RoomMembersListScreen.swift | 29 ++++++-- .../RoomMembersListScreenMemberCell.swift | 71 ++++++++++++------- .../View/UserProfileScreen.swift | 13 +++- .../UITests/UITestsAppCoordinator.swift | 3 +- .../RoomMembersListScreenViewModelTests.swift | 35 +++++---- 12 files changed, 176 insertions(+), 91 deletions(-) diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift index e254b779c6..4ffa256cb6 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift @@ -889,8 +889,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { } private func presentRoomMembersList() { - let parameters = RoomMembersListScreenCoordinatorParameters(mediaProvider: userSession.mediaProvider, + let parameters = RoomMembersListScreenCoordinatorParameters(clientProxy: userSession.clientProxy, roomProxy: roomProxy, + mediaProvider: userSession.mediaProvider, userIndicatorController: userIndicatorController, analytics: analytics) let coordinator = RoomMembersListScreenCoordinator(parameters: parameters) diff --git a/ElementX/Sources/Mocks/UserIdentityProxyMock.swift b/ElementX/Sources/Mocks/UserIdentityProxyMock.swift index 7a59583821..58d506ed0a 100644 --- a/ElementX/Sources/Mocks/UserIdentityProxyMock.swift +++ b/ElementX/Sources/Mocks/UserIdentityProxyMock.swift @@ -7,12 +7,12 @@ extension UserIdentityProxyMock { struct Configuration { - var isVerified = false + var verificationState: UserIdentityVerificationState = .notVerified } convenience init(configuration: Configuration) { self.init() - underlyingVerificationState = configuration.isVerified ? .verified : .notVerified + underlyingVerificationState = configuration.verificationState } } diff --git a/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift b/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift index f17948ccb0..494af173af 100644 --- a/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift +++ b/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift @@ -171,12 +171,20 @@ struct RoomMemberDetailsScreen_Previews: PreviewProvider, TestablePreview { static func makeViewModel(member: RoomMemberProxyMock) -> RoomMemberDetailsScreenViewModel { let roomProxyMock = JoinedRoomProxyMock(.init(name: "")) roomProxyMock.getMemberUserIDReturnValue = .success(member) + let clientProxyMock = ClientProxyMock(.init()) clientProxyMock.userIdentityForClosure = { userID in - let isVerified = userID == RoomMemberProxyMock.mockDan.userID - return .success(UserIdentityProxyMock(configuration: .init(isVerified: isVerified))) + let identity = switch userID { + case RoomMemberProxyMock.mockDan.userID: + UserIdentityProxyMock(configuration: .init(verificationState: .verified)) + default: + UserIdentityProxyMock(configuration: .init()) + } + + return .success(identity) } + // to avoid mock the call state for the account owner test case if member.userID != RoomMemberProxyMock.mockMe.userID { clientProxyMock.directRoomForUserIDReturnValue = .success("roomID") diff --git a/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenCoordinator.swift b/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenCoordinator.swift index a6c653f791..f117fb7175 100644 --- a/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenCoordinator.swift +++ b/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenCoordinator.swift @@ -9,8 +9,9 @@ import Combine import SwiftUI struct RoomMembersListScreenCoordinatorParameters { - let mediaProvider: MediaProviderProtocol + let clientProxy: ClientProxyProtocol let roomProxy: JoinedRoomProxyProtocol + let mediaProvider: MediaProviderProtocol let userIndicatorController: UserIndicatorControllerProtocol let analytics: AnalyticsService } @@ -31,7 +32,8 @@ final class RoomMembersListScreenCoordinator: CoordinatorProtocol { } init(parameters: RoomMembersListScreenCoordinatorParameters) { - viewModel = RoomMembersListScreenViewModel(roomProxy: parameters.roomProxy, + viewModel = RoomMembersListScreenViewModel(clientProxy: parameters.clientProxy, + roomProxy: parameters.roomProxy, mediaProvider: parameters.mediaProvider, userIndicatorController: parameters.userIndicatorController, analytics: parameters.analytics) diff --git a/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenModels.swift b/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenModels.swift index a9f6889a18..cfd436e490 100644 --- a/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenModels.swift +++ b/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenModels.swift @@ -29,10 +29,15 @@ enum RoomMembersListScreenMode { case banned } +struct RoomMemberListScreenEntry: Equatable { + let member: RoomMemberDetails + let verificationState: UserIdentityVerificationState +} + struct RoomMembersListScreenViewState: BindableState { - private var joinedMembers: [RoomMemberDetails] - private var invitedMembers: [RoomMemberDetails] - private var bannedMembers: [RoomMemberDetails] + private var joinedMembers: [RoomMemberListScreenEntry] + private var invitedMembers: [RoomMemberListScreenEntry] + private var bannedMembers: [RoomMemberListScreenEntry] let joinedMembersCount: Int var bannedMembersCount: Int { bannedMembers.count } @@ -44,9 +49,9 @@ struct RoomMembersListScreenViewState: BindableState { var bindings: RoomMembersListScreenViewStateBindings init(joinedMembersCount: Int, - joinedMembers: [RoomMemberDetails] = [], - invitedMembers: [RoomMemberDetails] = [], - bannedMembers: [RoomMemberDetails] = [], + joinedMembers: [RoomMemberListScreenEntry] = [], + invitedMembers: [RoomMemberListScreenEntry] = [], + bannedMembers: [RoomMemberListScreenEntry] = [], bindings: RoomMembersListScreenViewStateBindings) { self.joinedMembersCount = joinedMembersCount self.joinedMembers = joinedMembers @@ -55,19 +60,19 @@ struct RoomMembersListScreenViewState: BindableState { self.bindings = bindings } - var visibleJoinedMembers: [RoomMemberDetails] { + var visibleJoinedMembers: [RoomMemberListScreenEntry] { joinedMembers - .filter { $0.matches(searchQuery: bindings.searchQuery) } + .filter { $0.member.matches(searchQuery: bindings.searchQuery) } } - var visibleInvitedMembers: [RoomMemberDetails] { + var visibleInvitedMembers: [RoomMemberListScreenEntry] { invitedMembers - .filter { $0.matches(searchQuery: bindings.searchQuery) } + .filter { $0.member.matches(searchQuery: bindings.searchQuery) } } - var visibleBannedMembers: [RoomMemberDetails] { + var visibleBannedMembers: [RoomMemberListScreenEntry] { bannedMembers - .filter { $0.matches(searchQuery: bindings.searchQuery) } + .filter { $0.member.matches(searchQuery: bindings.searchQuery) } } } diff --git a/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenViewModel.swift b/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenViewModel.swift index 2c7ad25d35..bcd327ca73 100644 --- a/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomMemberListScreen/RoomMembersListScreenViewModel.swift @@ -11,6 +11,7 @@ import SwiftUI typealias RoomMembersListScreenViewModelType = StateStoreViewModel class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMembersListScreenViewModelProtocol { + private let clientProxy: ClientProxyProtocol private let roomProxy: JoinedRoomProxyProtocol private let userIndicatorController: UserIndicatorControllerProtocol private let analytics: AnalyticsService @@ -24,10 +25,12 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe } init(initialMode: RoomMembersListScreenMode = .members, + clientProxy: ClientProxyProtocol, roomProxy: JoinedRoomProxyProtocol, mediaProvider: MediaProviderProtocol, userIndicatorController: UserIndicatorControllerProtocol, analytics: AnalyticsService) { + self.clientProxy = clientProxy self.roomProxy = roomProxy self.userIndicatorController = userIndicatorController self.analytics = analytics @@ -59,22 +62,23 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe } func stop() { - hideLoader() + hideLoadingIndicator(Self.setupMembersLoadingIndicatorIdentifier) + hideLoadingIndicator(Self.updateStateLoadingIndicatorIdentifier) } // MARK: - Members private func setupMembers() { Task { - showLoader() + showLoadingIndicator(Self.setupMembersLoadingIndicatorIdentifier) await roomProxy.updateMembers() - hideLoader() + hideLoadingIndicator(Self.setupMembersLoadingIndicatorIdentifier) } - roomProxy.membersPublisher - .filter { !$0.isEmpty } + roomProxy.membersPublisher.combineLatest(roomProxy.identityStatusChangesPublisher) + .filter { !$0.0.isEmpty } .receive(on: DispatchQueue.main) - .sink { [weak self] members in + .sink { [weak self] members, _ in self?.updateState(members: members) } .store(in: &cancellables) @@ -87,11 +91,12 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe private func updateState(members: [RoomMemberProxyProtocol]) { Task { - showLoader() + showLoadingIndicator(Self.updateStateLoadingIndicatorIdentifier) let members = members.sorted() let roomMembersDetails = await buildMembersDetails(members: members) self.members = members + self.state = .init(joinedMembersCount: roomProxy.infoPublisher.value.joinedMembersCount, joinedMembers: roomMembersDetails.joinedMembers, invitedMembers: roomMembersDetails.invitedMembers, @@ -102,25 +107,32 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe self.state.canKickUsers = await (try? roomProxy.canUserKick(userID: roomProxy.ownUserID).get()) == true self.state.canBanUsers = await (try? roomProxy.canUserBan(userID: roomProxy.ownUserID).get()) == true - hideLoader() + hideLoadingIndicator(Self.updateStateLoadingIndicatorIdentifier) } } private func buildMembersDetails(members: [RoomMemberProxyProtocol]) async -> RoomMembersDetails { - await Task.detached { + await Task.detached { [clientProxy, roomProxy] in // accessing RoomMember's properties is very slow. We need to do it in a background thread. - var invitedMembers: [RoomMemberDetails] = .init() - var joinedMembers: [RoomMemberDetails] = .init() - var bannedMembers: [RoomMemberDetails] = .init() + var invitedMembers: [RoomMemberListScreenEntry] = .init() + var joinedMembers: [RoomMemberListScreenEntry] = .init() + var bannedMembers: [RoomMemberListScreenEntry] = .init() for member in members { + var verificationState: UserIdentityVerificationState = .notVerified + if roomProxy.isEncrypted, // We don't care about identity statuses on non-encrypted rooms + case let .success(userIdentity) = await clientProxy.userIdentity(for: member.userID), + let userIdentity { + verificationState = userIdentity.verificationState + } + switch member.membership { case .invite: - invitedMembers.append(.init(withProxy: member)) + invitedMembers.append(.init(member: .init(withProxy: member), verificationState: verificationState)) case .join: - joinedMembers.append(.init(withProxy: member)) + joinedMembers.append(.init(member: .init(withProxy: member), verificationState: verificationState)) case .ban: - bannedMembers.append(.init(withProxy: member)) + bannedMembers.append(.init(member: .init(withProxy: member), verificationState: verificationState)) default: continue } @@ -128,7 +140,7 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe return .init(invitedMembers: invitedMembers, joinedMembers: joinedMembers, - bannedMembers: bannedMembers.sorted { $0.id.localizedStandardCompare($1.id) == .orderedAscending }) // Re-sort ignoring display name. + bannedMembers: bannedMembers.sorted { $0.member.id.localizedStandardCompare($1.member.id) == .orderedAscending }) // Re-sort ignoring display name. } .value } @@ -215,18 +227,19 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe // MARK: - Indicators - private let userIndicatorID = UUID().uuidString + private static let setupMembersLoadingIndicatorIdentifier = "\(RoomMembersListScreenViewModel.self)-SetupMembers" + private static let updateStateLoadingIndicatorIdentifier = "\(RoomMembersListScreenViewModel.self)-UpdateState" - private func showLoader() { - userIndicatorController.submitIndicator(UserIndicator(id: userIndicatorID, + private func showLoadingIndicator(_ identifier: String) { + userIndicatorController.submitIndicator(UserIndicator(id: identifier, type: .modal(progress: .indeterminate, interactiveDismissDisabled: false, allowsInteraction: true), title: L10n.commonLoading, persistent: true), delay: .milliseconds(200)) } - private func hideLoader() { - userIndicatorController.retractIndicatorWithId(userIndicatorID) + private func hideLoadingIndicator(_ identifier: String) { + userIndicatorController.retractIndicatorWithId(identifier) } private func showManageMemberIndicator(title: String) { @@ -247,7 +260,7 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe } private struct RoomMembersDetails { - var invitedMembers: [RoomMemberDetails] - var joinedMembers: [RoomMemberDetails] - var bannedMembers: [RoomMemberDetails] + var invitedMembers: [RoomMemberListScreenEntry] + var joinedMembers: [RoomMemberListScreenEntry] + var bannedMembers: [RoomMemberListScreenEntry] } diff --git a/ElementX/Sources/Screens/RoomMemberListScreen/View/RoomMembersListManageMemberSheet.swift b/ElementX/Sources/Screens/RoomMemberListScreen/View/RoomMembersListManageMemberSheet.swift index 340c0a504e..775c291436 100644 --- a/ElementX/Sources/Screens/RoomMemberListScreen/View/RoomMembersListManageMemberSheet.swift +++ b/ElementX/Sources/Screens/RoomMemberListScreen/View/RoomMembersListManageMemberSheet.swift @@ -97,6 +97,7 @@ struct RoomMembersListManageMemberSheetLive_Previews: PreviewProvider { private extension RoomMembersListScreenViewModel { static var mock: RoomMembersListScreenViewModel { RoomMembersListScreenViewModel(initialMode: .members, + clientProxy: ClientProxyMock(.init()), roomProxy: JoinedRoomProxyMock(.init(members: .allMembersAsAdmin)), mediaProvider: MediaProviderMock(configuration: .init()), userIndicatorController: ServiceLocator.shared.userIndicatorController, diff --git a/ElementX/Sources/Screens/RoomMemberListScreen/View/RoomMembersListScreen.swift b/ElementX/Sources/Screens/RoomMemberListScreen/View/RoomMembersListScreen.swift index 06e8ba43ae..216ba778d2 100644 --- a/ElementX/Sources/Screens/RoomMemberListScreen/View/RoomMembersListScreen.swift +++ b/ElementX/Sources/Screens/RoomMemberListScreen/View/RoomMembersListScreen.swift @@ -59,23 +59,23 @@ struct RoomMembersListScreen: View { var roomMembers: some View { LazyVStack(alignment: .leading, spacing: 12) { - membersSection(data: context.viewState.visibleInvitedMembers, sectionTitle: L10n.screenRoomMemberListPendingHeaderTitle) - membersSection(data: context.viewState.visibleJoinedMembers, sectionTitle: L10n.screenRoomMemberListHeaderTitle(Int(context.viewState.joinedMembersCount))) + membersSection(entries: context.viewState.visibleInvitedMembers, sectionTitle: L10n.screenRoomMemberListPendingHeaderTitle) + membersSection(entries: context.viewState.visibleJoinedMembers, sectionTitle: L10n.screenRoomMemberListHeaderTitle(Int(context.viewState.joinedMembersCount))) } } var bannedUsers: some View { LazyVStack(alignment: .leading, spacing: 12) { - membersSection(data: context.viewState.visibleBannedMembers) + membersSection(entries: context.viewState.visibleBannedMembers) } } @ViewBuilder - private func membersSection(data: [RoomMemberDetails], sectionTitle: String? = nil) -> some View { - if !data.isEmpty { + private func membersSection(entries: [RoomMemberListScreenEntry], sectionTitle: String? = nil) -> some View { + if !entries.isEmpty { Section { - ForEach(data, id: \.id) { member in - RoomMembersListScreenMemberCell(member: member, context: context) + ForEach(entries, id: \.member.id) { entry in + RoomMembersListScreenMemberCell(listEntry: entry, context: context) } } header: { if let sectionTitle { @@ -179,7 +179,22 @@ struct RoomMembersListScreen_Previews: PreviewProvider, TestablePreview { members.append(.mockInvited) } + let clientProxyMock = ClientProxyMock(.init()) + clientProxyMock.userIdentityForClosure = { userID in + let identity = switch userID { + case RoomMemberProxyMock.mockAlice.userID: + UserIdentityProxyMock(configuration: .init(verificationState: .verified)) + case RoomMemberProxyMock.mockBob.userID: + UserIdentityProxyMock(configuration: .init(verificationState: .verificationViolation)) + default: + UserIdentityProxyMock(configuration: .init()) + } + + return .success(identity) + } + return RoomMembersListScreenViewModel(initialMode: initialMode, + clientProxy: clientProxyMock, roomProxy: JoinedRoomProxyMock(.init(name: "Some room", members: members, ownUserID: ownUserID, diff --git a/ElementX/Sources/Screens/RoomMemberListScreen/View/RoomMembersListScreenMemberCell.swift b/ElementX/Sources/Screens/RoomMemberListScreen/View/RoomMembersListScreenMemberCell.swift index 9cd8a71b10..5296f5f3a6 100644 --- a/ElementX/Sources/Screens/RoomMemberListScreen/View/RoomMembersListScreenMemberCell.swift +++ b/ElementX/Sources/Screens/RoomMemberListScreen/View/RoomMembersListScreenMemberCell.swift @@ -8,22 +8,22 @@ import SwiftUI struct RoomMembersListScreenMemberCell: View { - let member: RoomMemberDetails + let listEntry: RoomMemberListScreenEntry let context: RoomMembersListScreenViewModel.Context var body: some View { Button { - context.send(viewAction: .selectMember(member)) + context.send(viewAction: .selectMember(listEntry.member)) } label: { HStack(spacing: 8) { LoadableAvatarImage(url: avatarURL, name: avatarName, - contentID: member.id, + contentID: listEntry.member.id, avatarSize: .user(on: .roomDetails), mediaProvider: context.mediaProvider) .accessibilityHidden(true) - HStack(alignment: .firstTextBaseline, spacing: 4) { + HStack(alignment: .center, spacing: 4) { VStack(alignment: .leading, spacing: 0) { Text(title) .font(.compound.bodyMDSemibold) @@ -39,6 +39,8 @@ struct RoomMembersListScreenMemberCell: View { } .frame(maxWidth: .infinity, alignment: .leading) + VerificationBadge(verificationState: listEntry.verificationState) + if let role { Text(role) .font(.compound.bodyXS) @@ -52,7 +54,7 @@ struct RoomMembersListScreenMemberCell: View { } var role: String? { - switch member.role { + switch listEntry.member.role { case .administrator: L10n.screenRoomMemberListRoleAdministrator case .moderator: @@ -65,55 +67,72 @@ struct RoomMembersListScreenMemberCell: View { // Computed properties to hide the user's profile when banned. var title: String { - guard !member.isBanned else { return member.id } - return member.name ?? member.id + guard !listEntry.member.isBanned else { return listEntry.member.id } + return listEntry.member.name ?? listEntry.member.id } var subtitle: String? { - member.isBanned ? nil : member.id + listEntry.member.isBanned ? nil : listEntry.member.id } var avatarName: String? { - member.isBanned ? nil : member.name + listEntry.member.isBanned ? nil : listEntry.member.name } var avatarURL: URL? { - member.isBanned ? nil : member.avatarURL + listEntry.member.isBanned ? nil : listEntry.member.avatarURL } } struct RoomMembersListMemberCell_Previews: PreviewProvider, TestablePreview { - static let members: [RoomMemberProxyMock] = [ - .mockAlice, - .mockAdmin, - .mockModerator, - .init(with: .init(userID: "@nodisplayname:matrix.org", membership: .join)), - .init(with: .init(userID: "@avatar:matrix.org", displayName: "Avatar", avatarURL: .mockMXCUserAvatar, membership: .join)) + static let members: [RoomMemberListScreenEntry] = [ + .init(member: .init(withProxy: RoomMemberProxyMock.mockAlice), + verificationState: .notVerified), + .init(member: .init(withProxy: RoomMemberProxyMock.mockAdmin), + verificationState: .verified), + .init(member: .init(withProxy: RoomMemberProxyMock.mockModerator), + verificationState: .verificationViolation), + .init(member: .init(withProxy: RoomMemberProxyMock(with: .init(userID: "@nodisplayname:matrix.org", + membership: .join))), + verificationState: .notVerified), + .init(member: .init(withProxy: RoomMemberProxyMock(with: .init(userID: "@avatar:matrix.org", + displayName: "Avatar", + avatarURL: .mockMXCUserAvatar, + membership: .join))), + verificationState: .notVerified) ] - static let bannedMembers: [RoomMemberProxyMock] = [ - .init(with: .init(userID: "@nodisplayname:matrix.org", membership: .ban)), - .init(with: .init(userID: "@fake:matrix.org", displayName: "President", membership: .ban)), - .init(with: .init(userID: "@badavatar:matrix.org", avatarURL: .mockMXCUserAvatar, membership: .ban)) + static let bannedMembers: [RoomMemberListScreenEntry] = [ + .init(member: .init(withProxy: RoomMemberProxyMock(with: .init(userID: "@nodisplayname:matrix.org", + membership: .ban))), + verificationState: .notVerified), + .init(member: .init(withProxy: RoomMemberProxyMock(with: .init(userID: "@fake:matrix.org", + displayName: "President", + membership: .ban))), + verificationState: .verified), + .init(member: .init(withProxy: RoomMemberProxyMock(with: .init(userID: "@badavatar:matrix.org", + avatarURL: .mockMXCUserAvatar, + membership: .ban))), + verificationState: .verificationViolation) ] - static let viewModel = RoomMembersListScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Some room", - members: members)), + static let viewModel = RoomMembersListScreenViewModel(clientProxy: ClientProxyMock(.init()), + roomProxy: JoinedRoomProxyMock(.init(name: "Some room", members: [])), mediaProvider: MediaProviderMock(configuration: .init()), userIndicatorController: ServiceLocator.shared.userIndicatorController, analytics: ServiceLocator.shared.analytics) static var previews: some View { VStack(spacing: 12) { Section("Invited/Joined") { - ForEach(members, id: \.userID) { member in - RoomMembersListScreenMemberCell(member: .init(withProxy: member), context: viewModel.context) + ForEach(members, id: \.member.id) { entry in + RoomMembersListScreenMemberCell(listEntry: entry, context: viewModel.context) } } // Banned members should have their profiles hidden and the avatar should use the first letter from their user ID. Section("Banned") { - ForEach(bannedMembers, id: \.userID) { member in - RoomMembersListScreenMemberCell(member: .init(withProxy: member), context: viewModel.context) + ForEach(bannedMembers, id: \.member.id) { entry in + RoomMembersListScreenMemberCell(listEntry: entry, context: viewModel.context) } } } diff --git a/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift b/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift index c0c00dcca0..1dccb1c230 100644 --- a/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift +++ b/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift @@ -137,13 +137,22 @@ struct UserProfileScreen_Previews: PreviewProvider, TestablePreview { static func makeViewModel(userID: String) -> UserProfileScreenViewModel { let clientProxyMock = ClientProxyMock(.init()) + clientProxyMock.userIdentityForClosure = { userID in - let isVerified = userID == RoomMemberProxyMock.mockDan.userID - return .success(UserIdentityProxyMock(configuration: .init(isVerified: isVerified))) + let identity = switch userID { + case RoomMemberProxyMock.mockDan.userID: + UserIdentityProxyMock(configuration: .init(verificationState: .verified)) + default: + UserIdentityProxyMock(configuration: .init()) + } + + return .success(identity) } + if userID != RoomMemberProxyMock.mockMe.userID { clientProxyMock.directRoomForUserIDReturnValue = .success("roomID") } + return UserProfileScreenViewModel(userID: userID, isPresentedModally: false, clientProxy: clientProxyMock, diff --git a/ElementX/Sources/UITests/UITestsAppCoordinator.swift b/ElementX/Sources/UITests/UITestsAppCoordinator.swift index e21fd1e2fd..c981eae536 100644 --- a/ElementX/Sources/UITests/UITestsAppCoordinator.swift +++ b/ElementX/Sources/UITests/UITestsAppCoordinator.swift @@ -571,8 +571,9 @@ class MockScreen: Identifiable { case .roomMembersListScreenPendingInvites: let navigationStackCoordinator = NavigationStackCoordinator() let members: [RoomMemberProxyMock] = [.mockInvitedAlice, .mockBob, .mockCharlie] - let coordinator = RoomMembersListScreenCoordinator(parameters: .init(mediaProvider: MediaProviderMock(configuration: .init()), + let coordinator = RoomMembersListScreenCoordinator(parameters: .init(clientProxy: ClientProxyMock(.init()), roomProxy: JoinedRoomProxyMock(.init(name: "test", members: members)), + mediaProvider: MediaProviderMock(configuration: .init()), userIndicatorController: ServiceLocator.shared.userIndicatorController, analytics: ServiceLocator.shared.analytics)) navigationStackCoordinator.setRootCoordinator(coordinator) diff --git a/UnitTests/Sources/RoomMembersListScreenViewModelTests.swift b/UnitTests/Sources/RoomMembersListScreenViewModelTests.swift index c3a24a60da..7f118d39c9 100644 --- a/UnitTests/Sources/RoomMembersListScreenViewModelTests.swift +++ b/UnitTests/Sources/RoomMembersListScreenViewModelTests.swift @@ -40,8 +40,18 @@ class RoomMembersListScreenViewModelTests: XCTestCase { try await deferred.fulfill() - let sortedMembers: [RoomMemberProxyMock] = [.mockAdmin, .mockModerator, .mockAlice, .mockDan] - XCTAssertEqual(viewModel.state.visibleJoinedMembers, sortedMembers.map(RoomMemberDetails.init)) + let sortedMembers: [RoomMemberListScreenEntry] = [ + .init(member: .init(withProxy: RoomMemberProxyMock.mockAdmin), + verificationState: .notVerified), + .init(member: .init(withProxy: RoomMemberProxyMock.mockModerator), + verificationState: .notVerified), + .init(member: .init(withProxy: RoomMemberProxyMock.mockAlice), + verificationState: .notVerified), + .init(member: .init(withProxy: RoomMemberProxyMock.mockDan), + verificationState: .notVerified) + ] + + XCTAssertEqual(viewModel.state.visibleJoinedMembers, sortedMembers) } func testSearch() async throws { @@ -125,7 +135,7 @@ class RoomMembersListScreenViewModelTests: XCTestCase { // When tapping on another user in the list. let memberDetailsAction = deferFulfillment(viewModel.actions) { $0.isSelectMember } - guard let user = viewModel.state.visibleJoinedMembers.first(where: { $0.role == .user && $0.id != RoomMemberProxyMock.mockMe.userID }) else { + guard let user = viewModel.state.visibleJoinedMembers.first(where: { $0.member.role == .user && $0.member.id != RoomMemberProxyMock.mockMe.userID })?.member else { XCTFail("Expected to find a regular user.") return } @@ -145,7 +155,7 @@ class RoomMembersListScreenViewModelTests: XCTestCase { // When tapping on a user in the list. deferred = deferFulfillment(context.$viewState) { $0.bindings.memberToManage != nil } - guard let user = viewModel.state.visibleJoinedMembers.first(where: { $0.role == .user && $0.id != RoomMemberProxyMock.mockMe.userID }) else { + guard let user = viewModel.state.visibleJoinedMembers.first(where: { $0.member.role == .user && $0.member.id != RoomMemberProxyMock.mockMe.userID })?.member else { XCTFail("Expected to find a regular user.") return } @@ -166,7 +176,7 @@ class RoomMembersListScreenViewModelTests: XCTestCase { // When tapping on a moderator in the list. deferred = deferFulfillment(context.$viewState) { $0.bindings.memberToManage != nil } - guard let moderator = viewModel.state.visibleJoinedMembers.first(where: { $0.role == .moderator }) else { + guard let moderator = viewModel.state.visibleJoinedMembers.first(where: { $0.member.role == .moderator })?.member else { XCTFail("Expected to find a moderator.") return } @@ -186,7 +196,7 @@ class RoomMembersListScreenViewModelTests: XCTestCase { // When tapping on another administrator in the list. let memberDetailsAction = deferFulfillment(viewModel.actions) { $0.isSelectMember } - guard let admin = viewModel.state.visibleJoinedMembers.first(where: { $0.role == .administrator && $0.id != RoomMemberProxyMock.mockMe.userID }) else { + guard let admin = viewModel.state.visibleJoinedMembers.first(where: { $0.member.role == .administrator && $0.member.id != RoomMemberProxyMock.mockMe.userID })?.member else { XCTFail("Expected to find another admin.") return } @@ -205,7 +215,7 @@ class RoomMembersListScreenViewModelTests: XCTestCase { // When tapping on yourself in the list. let memberDetailsAction = deferFulfillment(viewModel.actions) { $0.isSelectMember } - guard let ownMember = viewModel.state.visibleJoinedMembers.first(where: { $0.id == RoomMemberProxyMock.mockMe.userID }) else { + guard let ownMember = viewModel.state.visibleJoinedMembers.first(where: { $0.member.id == RoomMemberProxyMock.mockMe.userID })?.member else { XCTFail("Expected to find own user admin.") return } @@ -225,7 +235,7 @@ class RoomMembersListScreenViewModelTests: XCTestCase { // When tapping on a banned member in the list. deferred = deferFulfillment(context.$viewState) { $0.bindings.alertInfo != nil } - guard let bannedMember = viewModel.state.visibleBannedMembers.first else { + guard let bannedMember = viewModel.state.visibleBannedMembers.first?.member else { XCTFail("Expected to find a banned user.") return } @@ -242,7 +252,7 @@ class RoomMembersListScreenViewModelTests: XCTestCase { let deferred = deferFulfillment(context.$viewState) { !$0.visibleJoinedMembers.isEmpty } try await deferred.fulfill() - context.send(viewAction: .kickMember(viewModel.state.visibleJoinedMembers[0])) + context.send(viewAction: .kickMember(viewModel.state.visibleJoinedMembers[0].member)) // Calling the mock won't actually change any view state, so sleep instead. try await Task.sleep(for: .milliseconds(100)) @@ -255,7 +265,7 @@ class RoomMembersListScreenViewModelTests: XCTestCase { let deferred = deferFulfillment(context.$viewState) { !$0.visibleJoinedMembers.isEmpty } try await deferred.fulfill() - context.send(viewAction: .banMember(viewModel.state.visibleJoinedMembers[0])) + context.send(viewAction: .banMember(viewModel.state.visibleJoinedMembers[0].member)) // Calling the mock won't actually change any view state, so sleep instead. try await Task.sleep(for: .milliseconds(100)) @@ -268,7 +278,7 @@ class RoomMembersListScreenViewModelTests: XCTestCase { let deferred = deferFulfillment(context.$viewState) { !$0.visibleJoinedMembers.isEmpty } try await deferred.fulfill() - context.send(viewAction: .unbanMember(viewModel.state.visibleJoinedMembers[0])) + context.send(viewAction: .unbanMember(viewModel.state.visibleJoinedMembers[0].member)) // Calling the mock won't actually change any view state, so sleep instead. try await Task.sleep(for: .milliseconds(100)) @@ -278,7 +288,8 @@ class RoomMembersListScreenViewModelTests: XCTestCase { private func setup(with members: [RoomMemberProxyMock]) { roomProxy = JoinedRoomProxyMock(.init(name: "test", members: members)) - viewModel = .init(roomProxy: roomProxy, + viewModel = .init(clientProxy: ClientProxyMock(.init()), + roomProxy: roomProxy, mediaProvider: MediaProviderMock(configuration: .init()), userIndicatorController: ServiceLocator.shared.userIndicatorController, analytics: ServiceLocator.shared.analytics) From d90648bbcffa34593401d78ecf2a0e001b04ec13 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Fri, 14 Feb 2025 12:05:22 +0200 Subject: [PATCH 6/9] Show a withdraw verification section on the room member details for users that have pinning violations. --- .../RoomMemberDetailsScreenModels.swift | 13 +++-- .../RoomMemberDetailsScreenViewModel.swift | 21 +++++-- .../View/RoomMemberDetailsScreen.swift | 56 +++++++++++++++---- 3 files changed, 69 insertions(+), 21 deletions(-) diff --git a/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenModels.swift b/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenModels.swift index 0c89fb0c88..3e49d7914e 100644 --- a/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenModels.swift +++ b/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenModels.swift @@ -17,7 +17,7 @@ enum RoomMemberDetailsScreenViewModelAction { struct RoomMemberDetailsScreenViewState: BindableState { let userID: String var memberDetails: RoomMemberDetails? - var isVerified: Bool? + var verificationState: UserIdentityVerificationState? var isOwnMemberDetails = false var isProcessingIgnoreRequest = false var dmRoomID: String? @@ -25,11 +25,15 @@ struct RoomMemberDetailsScreenViewState: BindableState { var bindings: RoomMemberDetailsScreenViewStateBindings var showVerifiedBadge: Bool { - isVerified == true // We purposely show the badge on your own account for consistency with Web. + verificationState == .verified // We purposely show the badge on your own account for consistency with Web. } - var showVerificationSection: Bool { - isVerified == false && !isOwnMemberDetails + var showVerifyIdentitySection: Bool { + verificationState == .notVerified && !isOwnMemberDetails + } + + var showWithdrawVerificationSection: Bool { + verificationState == .verificationViolation && !isOwnMemberDetails } } @@ -90,6 +94,7 @@ enum RoomMemberDetailsScreenViewAction { case createDirectChat case startCall(roomID: String) case verifyUser + case withdrawVerification } enum RoomMemberDetailsScreenAlertType: Hashable { diff --git a/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenViewModel.swift b/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenViewModel.swift index 96ebbca5f7..a2d464c404 100644 --- a/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomMemberDetailsScreen/RoomMemberDetailsScreenViewModel.swift @@ -42,10 +42,20 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro super.init(initialViewState: initialViewState, mediaProvider: mediaProvider) showMemberLoadingIndicator() + Task { await loadMember() hideMemberLoadingIndicator() } + + roomProxy.identityStatusChangesPublisher + .receive(on: DispatchQueue.main) + .sink { changes in + if changes.map(\.userId).contains(userID) { + Task { await self.loadMember() } + } + } + .store(in: &cancellables) } // MARK: - Public @@ -77,16 +87,15 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro actionsSubject.send(.startCall(roomID: roomID)) case .verifyUser: actionsSubject.send(.verifyUser(userID: state.userID)) + case .withdrawVerification: + Task { await clientProxy.withdrawUserIdentityVerification(state.userID) } } } // MARK: - Private private func loadMember() async { - async let memberResult = roomProxy.getMember(userID: state.userID) - async let identityResult = clientProxy.userIdentity(for: state.userID) - - switch await memberResult { + switch await roomProxy.getMember(userID: state.userID) { case .success(let member): roomMemberProxy = member state.memberDetails = RoomMemberDetails(withProxy: member) @@ -105,8 +114,8 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro actionsSubject.send(.openUserProfile) } - if case let .success(.some(identity)) = await identityResult { - state.isVerified = identity.verificationState == .verified + if case let .success(.some(identity)) = await clientProxy.userIdentity(for: state.userID) { + state.verificationState = identity.verificationState } else { MXLog.error("Failed to find the member's identity.") } diff --git a/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift b/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift index 494af173af..0e30b172ec 100644 --- a/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift +++ b/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift @@ -15,7 +15,9 @@ struct RoomMemberDetailsScreen: View { Form { headerSection - verificationSection + if context.viewState.showVerifyIdentitySection { + verificationSection + } if context.viewState.memberDetails != nil, !context.viewState.isOwnMemberDetails { blockUserSection @@ -46,7 +48,14 @@ struct RoomMemberDetailsScreen: View { mediaProvider: context.mediaProvider) { url in context.send(viewAction: .displayAvatar(url)) } footer: { - otherUserFooter + VStack(spacing: 24) { + if context.viewState.showWithdrawVerificationSection { + withdrawVerificationSection + } + + otherUserFooter + } + .padding(.top, 24) } } else { AvatarHeaderView(user: UserProfileProxy(userID: context.viewState.userID), @@ -56,6 +65,26 @@ struct RoomMemberDetailsScreen: View { } } + private var withdrawVerificationSection: some View { + VStack(spacing: 16) { + if let memberDetails = context.viewState.memberDetails { + Text(L10n.cryptoIdentityChangeProfilePinViolation(memberDetails.name ?? memberDetails.id)) + .foregroundStyle(.compound.textCriticalPrimary) + .font(.compound.bodyMDSemibold) + } else { + Text(L10n.cryptoIdentityChangeProfilePinViolation(context.viewState.userID)) + .foregroundStyle(.compound.textCriticalPrimary) + .font(.compound.bodyMDSemibold) + } + + Button(L10n.cryptoIdentityChangeWithdrawVerificationAction) { + context.send(viewAction: .withdrawVerification) + } + .buttonStyle(.compound(.secondary, size: .medium)) + } + .padding(.horizontal, 16) + } + private var otherUserFooter: some View { HStack(spacing: 8) { if context.viewState.memberDetails != nil, !context.viewState.isOwnMemberDetails { @@ -84,18 +113,14 @@ struct RoomMemberDetailsScreen: View { .buttonStyle(FormActionButtonStyle(title: L10n.actionShare)) } } - .padding(.top, 32) } @ViewBuilder var verificationSection: some View { - if context.viewState.showVerificationSection { - Section { - ListRow(label: .default(title: L10n.commonVerifyUser, icon: \.lock), - kind: .button { - context.send(viewAction: .verifyUser) - }) - } + Section { + ListRow(label: .default(title: L10n.commonVerifyUser, icon: \.lock), kind: .button { + context.send(viewAction: .verifyUser) + }) } } @@ -138,6 +163,7 @@ struct RoomMemberDetailsScreen: View { struct RoomMemberDetailsScreen_Previews: PreviewProvider, TestablePreview { static let verifiedUserViewModel = makeViewModel(member: .mockDan) + static let verificationViolationUserViewModel = makeViewModel(member: .mockBob) static let otherUserViewModel = makeViewModel(member: .mockAlice) static let accountOwnerViewModel = makeViewModel(member: .mockMe) static let ignoredUserViewModel = makeViewModel(member: .mockIgnored) @@ -145,9 +171,15 @@ struct RoomMemberDetailsScreen_Previews: PreviewProvider, TestablePreview { static var previews: some View { RoomMemberDetailsScreen(context: verifiedUserViewModel.context) .snapshotPreferences(expect: verifiedUserViewModel.context.$viewState.map { state in - state.isVerified == true + state.verificationState == .verified }) .previewDisplayName("Verified User") + + RoomMemberDetailsScreen(context: verificationViolationUserViewModel.context) + .snapshotPreferences(expect: verificationViolationUserViewModel.context.$viewState.map { state in + state.verificationState == .verificationViolation + }) + .previewDisplayName("Verification Violation User") RoomMemberDetailsScreen(context: otherUserViewModel.context) .snapshotPreferences(expect: otherUserViewModel.context.$viewState.map { state in @@ -178,6 +210,8 @@ struct RoomMemberDetailsScreen_Previews: PreviewProvider, TestablePreview { let identity = switch userID { case RoomMemberProxyMock.mockDan.userID: UserIdentityProxyMock(configuration: .init(verificationState: .verified)) + case RoomMemberProxyMock.mockBob.userID: + UserIdentityProxyMock(configuration: .init(verificationState: .verificationViolation)) default: UserIdentityProxyMock(configuration: .init()) } From 621b0f1b0fb2906df926ae2285a52ca806b05c0b Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Fri, 14 Feb 2025 12:55:19 +0200 Subject: [PATCH 7/9] Remove the verification section from the profile screen as there's no reliable way to keep it up to date - the underlying Rust SDK Olm Machine can be rebuilt without notice which would break any existing user identity change streams. --- .../FlowCoordinators/RoomFlowCoordinator.swift | 2 -- .../UserSessionFlowCoordinator.swift | 2 -- .../UserProfileScreenCoordinator.swift | 3 --- .../UserProfileScreenModels.swift | 6 ------ .../UserProfileScreenViewModel.swift | 2 -- .../View/UserProfileScreen.swift | 16 +--------------- 6 files changed, 1 insertion(+), 30 deletions(-) diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift index 4ffa256cb6..d5c4eaee51 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift @@ -1276,8 +1276,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { stateMachine.tryEvent(.startChildFlow(roomID: roomID, via: [], entryPoint: .room)) case .startCall(let roomID): Task { await self.presentCallScreen(roomID: roomID) } - case .verifyUser(let userID): - actionsSubject.send(.verifyUser(userID: userID)) case .dismiss: break // Not supported when pushed. } diff --git a/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift index b11197ece1..73cdc3cf23 100644 --- a/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift @@ -923,8 +923,6 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol { stateMachine.processEvent(.selectRoom(roomID: roomID, via: [], entryPoint: .room)) case .startCall(let roomID): Task { await self.presentCallScreen(roomID: roomID, notifyOtherParticipants: false) } - case .verifyUser(let userID): - presentSessionVerificationScreen(flow: .userIntiator(userID: userID)) case .dismiss: navigationSplitCoordinator.setSheetCoordinator(nil) } diff --git a/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenCoordinator.swift b/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenCoordinator.swift index a18064d9c8..3eb074ca76 100644 --- a/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenCoordinator.swift +++ b/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenCoordinator.swift @@ -20,7 +20,6 @@ struct UserProfileScreenCoordinatorParameters { enum UserProfileScreenCoordinatorAction { case openDirectChat(roomID: String) case startCall(roomID: String) - case verifyUser(userID: String) case dismiss } @@ -52,8 +51,6 @@ final class UserProfileScreenCoordinator: CoordinatorProtocol { actionsSubject.send(.openDirectChat(roomID: roomID)) case .startCall(let roomID): actionsSubject.send(.startCall(roomID: roomID)) - case .verifyUser(let userID): - actionsSubject.send(.verifyUser(userID: userID)) case .dismiss: actionsSubject.send(.dismiss) } diff --git a/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenModels.swift b/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenModels.swift index d0b7448ffd..03eea94913 100644 --- a/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenModels.swift +++ b/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenModels.swift @@ -10,7 +10,6 @@ import Foundation enum UserProfileScreenViewModelAction { case openDirectChat(roomID: String) case startCall(roomID: String) - case verifyUser(userID: String) case dismiss } @@ -29,10 +28,6 @@ struct UserProfileScreenViewState: BindableState { var showVerifiedBadge: Bool { isVerified == true // We purposely show the badge on your own account for consistency with Web. } - - var showVerificationSection: Bool { - isVerified == false && !isOwnUser - } } struct UserProfileScreenViewStateBindings { @@ -48,7 +43,6 @@ enum UserProfileScreenViewAction { case openDirectChat case createDirectChat case startCall(roomID: String) - case verifyUser case dismiss } diff --git a/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenViewModel.swift b/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenViewModel.swift index 8ea0203b5f..aa65356188 100644 --- a/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenViewModel.swift +++ b/ElementX/Sources/Screens/UserProfileScreen/UserProfileScreenViewModel.swift @@ -66,8 +66,6 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr Task { await createDirectChat() } case .startCall(let roomID): actionsSubject.send(.startCall(roomID: roomID)) - case .verifyUser: - actionsSubject.send(.verifyUser(userID: state.userID)) case .dismiss: actionsSubject.send(.dismiss) } diff --git a/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift b/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift index 1dccb1c230..13cbf88762 100644 --- a/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift +++ b/ElementX/Sources/Screens/UserProfileScreen/View/UserProfileScreen.swift @@ -14,8 +14,6 @@ struct UserProfileScreen: View { var body: some View { Form { headerSection - - verificationSection } .compoundList() .navigationTitle(L10n.screenRoomMemberDetailsTitle) @@ -83,19 +81,7 @@ struct UserProfileScreen: View { } .padding(.top, 32) } - - @ViewBuilder - var verificationSection: some View { - if context.viewState.showVerificationSection { - Section { - ListRow(label: .default(title: L10n.commonVerifyUser, icon: \.lock), - kind: .button { - context.send(viewAction: .verifyUser) - }) - } - } - } - + @ToolbarContentBuilder private var toolbar: some ToolbarContent { if context.viewState.isPresentedModally { From e2ce4ffd6871bb011cde238adb285e20763ed78b Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Fri, 14 Feb 2025 13:31:47 +0200 Subject: [PATCH 8/9] Update preview test snapshots --- .../PreviewTests/test_joinRoomScreen-iPad-en-GB.Knocked.png | 4 ++-- .../PreviewTests/test_joinRoomScreen-iPad-pseudo.Knocked.png | 4 ++-- .../test_joinRoomScreen-iPhone-16-en-GB.Knocked.png | 4 ++-- .../test_joinRoomScreen-iPhone-16-pseudo.Knocked.png | 4 ++-- .../PreviewTests/test_roomHeaderView-iPad-en-GB.1.png | 4 ++-- .../PreviewTests/test_roomHeaderView-iPad-en-GB.2.png | 3 --- .../PreviewTests/test_roomHeaderView-iPad-pseudo.1.png | 4 ++-- .../PreviewTests/test_roomHeaderView-iPad-pseudo.2.png | 3 --- .../PreviewTests/test_roomHeaderView-iPhone-16-en-GB.1.png | 4 ++-- .../PreviewTests/test_roomHeaderView-iPhone-16-en-GB.2.png | 3 --- .../PreviewTests/test_roomHeaderView-iPhone-16-pseudo.1.png | 4 ++-- .../PreviewTests/test_roomHeaderView-iPhone-16-pseudo.2.png | 3 --- .../test_roomMemberDetailsScreen-iPad-en-GB.Account-Owner.png | 4 ++-- .../test_roomMemberDetailsScreen-iPad-en-GB.Ignored-User.png | 4 ++-- .../test_roomMemberDetailsScreen-iPad-en-GB.Other-User.png | 4 ++-- ...erDetailsScreen-iPad-en-GB.Verification-Violation-User.png | 3 +++ .../test_roomMemberDetailsScreen-iPad-en-GB.Verified-User.png | 4 ++-- ...test_roomMemberDetailsScreen-iPad-pseudo.Account-Owner.png | 4 ++-- .../test_roomMemberDetailsScreen-iPad-pseudo.Ignored-User.png | 4 ++-- .../test_roomMemberDetailsScreen-iPad-pseudo.Other-User.png | 4 ++-- ...rDetailsScreen-iPad-pseudo.Verification-Violation-User.png | 3 +++ ...test_roomMemberDetailsScreen-iPad-pseudo.Verified-User.png | 4 ++-- ..._roomMemberDetailsScreen-iPhone-16-en-GB.Account-Owner.png | 4 ++-- ...t_roomMemberDetailsScreen-iPhone-16-en-GB.Ignored-User.png | 4 ++-- ...est_roomMemberDetailsScreen-iPhone-16-en-GB.Other-User.png | 4 ++-- ...ailsScreen-iPhone-16-en-GB.Verification-Violation-User.png | 3 +++ ..._roomMemberDetailsScreen-iPhone-16-en-GB.Verified-User.png | 4 ++-- ...roomMemberDetailsScreen-iPhone-16-pseudo.Account-Owner.png | 4 ++-- ..._roomMemberDetailsScreen-iPhone-16-pseudo.Ignored-User.png | 4 ++-- ...st_roomMemberDetailsScreen-iPhone-16-pseudo.Other-User.png | 4 ++-- ...ilsScreen-iPhone-16-pseudo.Verification-Violation-User.png | 3 +++ ...roomMemberDetailsScreen-iPhone-16-pseudo.Verified-User.png | 4 ++-- .../test_roomMembersListMemberCell-iPad-en-GB.1.png | 4 ++-- .../test_roomMembersListMemberCell-iPad-pseudo.1.png | 4 ++-- .../test_roomMembersListMemberCell-iPhone-16-en-GB.1.png | 4 ++-- .../test_roomMembersListMemberCell-iPhone-16-pseudo.1.png | 4 ++-- .../test_roomMembersListScreen-iPad-en-GB.Admin-Members.png | 4 ++-- .../test_roomMembersListScreen-iPad-en-GB.Invites.png | 4 ++-- .../test_roomMembersListScreen-iPad-en-GB.Member.png | 4 ++-- .../test_roomMembersListScreen-iPad-pseudo.Admin-Members.png | 4 ++-- .../test_roomMembersListScreen-iPad-pseudo.Invites.png | 4 ++-- .../test_roomMembersListScreen-iPad-pseudo.Member.png | 4 ++-- ...st_roomMembersListScreen-iPhone-16-en-GB.Admin-Members.png | 4 ++-- .../test_roomMembersListScreen-iPhone-16-en-GB.Invites.png | 4 ++-- .../test_roomMembersListScreen-iPhone-16-en-GB.Member.png | 4 ++-- ...t_roomMembersListScreen-iPhone-16-pseudo.Admin-Members.png | 4 ++-- .../test_roomMembersListScreen-iPhone-16-pseudo.Invites.png | 4 ++-- .../test_roomMembersListScreen-iPhone-16-pseudo.Member.png | 4 ++-- .../PreviewTests/test_roomScreen-iPad-en-GB.1.png | 4 ++-- .../PreviewTests/test_roomScreen-iPad-pseudo.1.png | 4 ++-- .../PreviewTests/test_roomScreen-iPhone-16-en-GB.1.png | 4 ++-- .../PreviewTests/test_roomScreen-iPhone-16-pseudo.1.png | 4 ++-- .../PreviewTests/test_timelineView-iPad-en-GB.1.png | 4 ++-- .../PreviewTests/test_timelineView-iPad-pseudo.1.png | 4 ++-- .../PreviewTests/test_timelineView-iPhone-16-en-GB.1.png | 4 ++-- .../PreviewTests/test_timelineView-iPhone-16-pseudo.1.png | 4 ++-- .../test_userProfileScreen-iPad-en-GB.Other-User.png | 4 ++-- .../test_userProfileScreen-iPad-pseudo.Other-User.png | 4 ++-- .../test_userProfileScreen-iPhone-16-en-GB.Other-User.png | 4 ++-- .../test_userProfileScreen-iPhone-16-pseudo.Other-User.png | 4 ++-- 60 files changed, 116 insertions(+), 116 deletions(-) delete mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-en-GB.2.png delete mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-pseudo.2.png delete mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-en-GB.2.png delete mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-pseudo.2.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Verification-Violation-User.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Verification-Violation-User.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Verification-Violation-User.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Verification-Violation-User.png diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-en-GB.Knocked.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-en-GB.Knocked.png index 375ce156ab..289e7066bb 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-en-GB.Knocked.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-en-GB.Knocked.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ad1568981acd0a49c17795c4f9bf47c0270007639dd61effb68d708d49a8123 -size 111376 +oid sha256:153b4927280abdaa674e93f843c84b6dd1a23070c37556d57294d1504759ff2d +size 111371 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-pseudo.Knocked.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-pseudo.Knocked.png index 60de69065c..e52356f745 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-pseudo.Knocked.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-pseudo.Knocked.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c71906723f41774d71975cefc46b0ab8415e0fdebb63ec8768480a32935aeadb -size 123103 +oid sha256:aa9c4ce4236f90ab89039f6353aa28091c2127b9d2acec0c808492f2b88750e3 +size 123098 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPhone-16-en-GB.Knocked.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPhone-16-en-GB.Knocked.png index efd159c58d..db6d8db2f1 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPhone-16-en-GB.Knocked.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPhone-16-en-GB.Knocked.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:19e3709844d8e70eebcd04eea5b56f2c32cb29c50626a3ae2834d839b8904efd -size 68156 +oid sha256:8a9575ea8743524b675a174ae1e5b7bed6d85ac01f6b833daec9739997b0b2da +size 68180 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPhone-16-pseudo.Knocked.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPhone-16-pseudo.Knocked.png index 0ac5e10add..f72c1542ea 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPhone-16-pseudo.Knocked.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_joinRoomScreen-iPhone-16-pseudo.Knocked.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ae6d231128edddb04ba4fffa915c2fcf1169ea28196cce8431da8d3eaa43d4e3 -size 82070 +oid sha256:48cc5116b97690c21daad083a15e9266068f9196a426b938020d3b57f8a4d8d2 +size 82093 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-en-GB.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-en-GB.1.png index 0723203fb7..0e56149265 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-en-GB.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-en-GB.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b8d4f33061bf7a6298eff4e3ffb63194b7b0eee56f2677c55e0db5c4db4e8a05 -size 19820 +oid sha256:5a3fcbc84d86ab21cfb58787fd83ab8e46e48e2fe35acaec61dff7f72fc0f938 +size 73712 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-en-GB.2.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-en-GB.2.png deleted file mode 100644 index 08d6635efc..0000000000 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-en-GB.2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:94a649334de3e92c04c8c5fa24606ce4338b38867d3af71ba044ebc199bbf8d5 -size 11439 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-pseudo.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-pseudo.1.png index 0723203fb7..0e56149265 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-pseudo.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-pseudo.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b8d4f33061bf7a6298eff4e3ffb63194b7b0eee56f2677c55e0db5c4db4e8a05 -size 19820 +oid sha256:5a3fcbc84d86ab21cfb58787fd83ab8e46e48e2fe35acaec61dff7f72fc0f938 +size 73712 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-pseudo.2.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-pseudo.2.png deleted file mode 100644 index 08d6635efc..0000000000 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPad-pseudo.2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:94a649334de3e92c04c8c5fa24606ce4338b38867d3af71ba044ebc199bbf8d5 -size 11439 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-en-GB.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-en-GB.1.png index c4b0280b36..897f50e89c 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-en-GB.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-en-GB.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0a28fd17b8b3cbaa0d27c70019904244d5d29ee2fc83266512e8ae3b386e32cf -size 15862 +oid sha256:1dfa74df7fac6d93e37ee9332a59b442c97a912261bc40b73c786090d613f259 +size 56152 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-en-GB.2.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-en-GB.2.png deleted file mode 100644 index 7825f2956a..0000000000 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-en-GB.2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:07945ef1e674a1744a26d59745956b94201a9a2b0fdb9a1c15933c32ce246e89 -size 7886 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-pseudo.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-pseudo.1.png index c4b0280b36..897f50e89c 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-pseudo.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-pseudo.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0a28fd17b8b3cbaa0d27c70019904244d5d29ee2fc83266512e8ae3b386e32cf -size 15862 +oid sha256:1dfa74df7fac6d93e37ee9332a59b442c97a912261bc40b73c786090d613f259 +size 56152 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-pseudo.2.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-pseudo.2.png deleted file mode 100644 index 7825f2956a..0000000000 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomHeaderView-iPhone-16-pseudo.2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:07945ef1e674a1744a26d59745956b94201a9a2b0fdb9a1c15933c32ce246e89 -size 7886 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Account-Owner.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Account-Owner.png index 13cc052c03..f46cefbf9b 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Account-Owner.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Account-Owner.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb9a139e108b9cca1fceafa4fb2d4b2c0ea7a8b76a916a72cab682f1895a2cbb -size 180293 +oid sha256:bc9057e946a55019caf464ab7437197b5bd0ab5e83076aba8a64bf65c309773b +size 180336 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Ignored-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Ignored-User.png index f3302ce486..417ae5e0eb 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Ignored-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Ignored-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bc7992df6c2b7227c500f84531bdac9577db2cf067cb6aa9a81b81a8936771e4 -size 114445 +oid sha256:75cd91c40c97f338248fb5d5e76a291010115220c4094e27058206b5d7f1307b +size 114637 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Other-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Other-User.png index b1dafa653f..e8cc8e9c07 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Other-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Other-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eb8a03e056c72838db67ac97b012792f1d98985952dcaeffe80455363b729a5a -size 114232 +oid sha256:a36746c71d1e8fc4379b20b17adeed7af104bd2bf2bc0f59fb9c9cd4b77f6bba +size 114418 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Verification-Violation-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Verification-Violation-User.png new file mode 100644 index 0000000000..e7d820f72d --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Verification-Violation-User.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcf2cefb0e51250c908006f9380d69d2ecf46a71c4a86aa54e20995498c0eb47 +size 125040 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Verified-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Verified-User.png index d717b5811d..5340aa6ded 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Verified-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-en-GB.Verified-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e764eb1952e4820a15affa00461fb1e2f4a3de0b7ff498560aab738e042c2c0b -size 199433 +oid sha256:d4cca2b5da6c0a8bd3946a9d2a7ffb5b23a448c3e07eb0a5dea7bdab025c76c9 +size 199464 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Account-Owner.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Account-Owner.png index a634689320..d3097b0d33 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Account-Owner.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Account-Owner.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f2f03c0e35ba417a0b55d2cade9bb8eeada26f0514497b411adc61675b25c03a -size 180559 +oid sha256:48b686ff1f24cd842f4d8ae28c11c3a62113d2137e974c68f52e551bdb4514d8 +size 180604 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Ignored-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Ignored-User.png index e65feeeccb..b6d00e49d4 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Ignored-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Ignored-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:26810d28eb8d22229c2fb6259d44182e8f459efc13d3da72af855c3bd217894c -size 116662 +oid sha256:763fb73d2174b8c43a13eda6d833cfa59514069f3e5343d149f5b4db16db0ef2 +size 116882 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Other-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Other-User.png index 80c0fbfdee..586f3f501e 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Other-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Other-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4deab2abb40430b6c26169284463fcb45ca30f93b703906e83a7a80b0dd44085 -size 116224 +oid sha256:add76379b3faa0915ddacb2f0fba8f0dafa629fcee802230b7b6fa04f84d87d1 +size 116404 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Verification-Violation-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Verification-Violation-User.png new file mode 100644 index 0000000000..dfa7414468 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Verification-Violation-User.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:622e29540af65ff83e1b0f4799431b3a44edba542d208f007f3027c612e3e043 +size 133323 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Verified-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Verified-User.png index ab75e02f2c..04d68c95b8 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Verified-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPad-pseudo.Verified-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c1d159bceea6b6a367d6f6d1adc3c91f7c8ed5a89a12cc76d950108505e50834 -size 200973 +oid sha256:72f3469670b4e242ff96cfd50116c4413b50dc59f229257eeaddea84fc802bdc +size 201004 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Account-Owner.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Account-Owner.png index afd9a8ea95..90108ece13 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Account-Owner.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Account-Owner.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6bef0734ddc98e3d468375a8ed95de83880740c3cd9393506e49004f88a9c1b1 -size 121431 +oid sha256:56b877e9188f4dfaab208f93d34fe1dbaceed62e5122a87bbf5b5708d59ef789 +size 121429 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Ignored-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Ignored-User.png index fe331a1eec..72df201744 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Ignored-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Ignored-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:99d9738fe1e134a9570a510ee4e0a7622bccc0edda2316d7e083cb6800f47567 -size 66185 +oid sha256:7cf3cda095d77c4336f766f2e8c42a8a6be21c460464080b33e4819fd955009e +size 65826 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Other-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Other-User.png index 3a551369d0..34ca074af5 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Other-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Other-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2890c691ada40cd89e8659f9e4397e5f2e0958cc3a7540d7f42f0d525fda4f46 -size 65267 +oid sha256:33df32f5444f672baadb0028384d11d2385c49eaf87734587efe686dfeb07ed4 +size 64908 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Verification-Violation-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Verification-Violation-User.png new file mode 100644 index 0000000000..fa611bcd75 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Verification-Violation-User.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03c2ebe4a22b3b8422e5f320f57a59ac2b8038c057327657878378458e5328d5 +size 74321 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Verified-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Verified-User.png index ed1fd8c86e..fa943327ec 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Verified-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-en-GB.Verified-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f47c8be31c2dfb8109e021b872ddce7ce7d38a5015ada1a5332ee522b25f0382 -size 138264 +oid sha256:5030171dd1afe4cbf988eaca778cf9ed0500f7284bba7ac51fb3243e1f632899 +size 138283 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Account-Owner.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Account-Owner.png index 331bad7517..7c8e56c58d 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Account-Owner.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Account-Owner.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:22eb5c47c43b1c9fb7bc0f2806a90750374ad3825ab0d017d57bf0fd61d696b0 -size 122013 +oid sha256:6bdf3c45eb5a7ec4e44cf20b1a667f934b51c6316d05c85026749820544518df +size 122011 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Ignored-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Ignored-User.png index 3f3c00f2f2..460de8756a 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Ignored-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Ignored-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4a076ef632d402d507a09abaa38822a81a2a1a094aaee6de62e2aed796478266 -size 74470 +oid sha256:8a75782f44f8492435c9ebab3708644e955f14dca3ac35ab615a69984c7a71fa +size 74437 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Other-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Other-User.png index 028c81056c..bec04f3bfb 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Other-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Other-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c796a02083a8469da92b6d764092caf259a0f6ee4ff52baf7851e5fcfa2be76d -size 73660 +oid sha256:703f8fdb10d5d1081eb1bfddef855de60c9bb21ee90ff08420813fab23ee3ba6 +size 73622 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Verification-Violation-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Verification-Violation-User.png new file mode 100644 index 0000000000..d3c6813d46 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Verification-Violation-User.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b02fe793ca33790c1c6da7b1eabea1b828324c6faeacf242857d26b0b94eeb2 +size 93276 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Verified-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Verified-User.png index 6c48bf75f8..20be829c59 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Verified-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMemberDetailsScreen-iPhone-16-pseudo.Verified-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:01b00054f275cb3ae4185449e7c5cbe375180260f0cde860ab290ed5dc6757b0 -size 146295 +oid sha256:2cc7c0a660c1ddf91e1f7336525dd18ce8a6a3ff1e1746e070119fe74b2a539c +size 146322 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPad-en-GB.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPad-en-GB.1.png index 97007e94e6..ec7448e3e3 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPad-en-GB.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPad-en-GB.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:02f47841f18c62a867c4ff1a23bf16edf17c81f5e97f249c2cff30a9d6c869f6 -size 169210 +oid sha256:150439a358f12324fd477216dffe3cbf9feccc704f019e00ad4f43e153bb97fa +size 172233 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPad-pseudo.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPad-pseudo.1.png index aec88975c5..456a07adb2 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPad-pseudo.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPad-pseudo.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2e5bb0918b63578e8aa80fe8eaa088f4cff4eea4d4ab886b945362186e85ae5c -size 172967 +oid sha256:9f2e7d68d38ac78087a52dfd0ef401fccda75d9a7112bc357ae5b034cecb48db +size 175918 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPhone-16-en-GB.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPhone-16-en-GB.1.png index 1673f0fa5c..8edb0a63aa 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPhone-16-en-GB.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPhone-16-en-GB.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a71ee5cc84935ecdfaa5fd164b46f01c1841ea4469282eaa424d729a65906148 -size 113290 +oid sha256:818255f45004091e759445a5541c9b04aa6c58926c7479e5e48f2da9ca9c0222 +size 115529 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPhone-16-pseudo.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPhone-16-pseudo.1.png index 9c135502ce..6ada96880e 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPhone-16-pseudo.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListMemberCell-iPhone-16-pseudo.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f67432fd158f5f91089243ea9919ade5e8b10a481625715a413d1e6ae580663 -size 117653 +oid sha256:803e62688fba1c2c652a59f52784e39da86f6a80dee0e0862925e75d80bf83cd +size 119715 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-en-GB.Admin-Members.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-en-GB.Admin-Members.png index 32d7124031..4627572047 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-en-GB.Admin-Members.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-en-GB.Admin-Members.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b1157284b4d3bd61c1ed44c4f8c49cfd693cea4634f785d78a738e291d39d08e -size 132965 +oid sha256:3e9df975598876636a317b5c6ab5a0f8d38c9afb7be4e25c4e6fad0c46bf5719 +size 134459 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-en-GB.Invites.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-en-GB.Invites.png index 7b2d6c4781..f4cd79cf09 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-en-GB.Invites.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-en-GB.Invites.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:765e253eb1ab6eb5d9a77bc8b0a6c5d7e3ed064343ac055f9702b5fc810763aa -size 136303 +oid sha256:feca48e2dcc6dc7f029b1b39716d3b1af94e1a12b6afc94cbf061fc68f2f3cac +size 137742 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-en-GB.Member.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-en-GB.Member.png index ed51fc2be8..ff6ececbec 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-en-GB.Member.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-en-GB.Member.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:02a3fb3f4dd20a12d2ff00ea73a6f88d4a30e96de1d6522b57a9c88ee1a7e05d -size 125648 +oid sha256:c60d9ebc5781792b45e0237d8f69c524af59865f32e387c762f306744c411401 +size 127049 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-pseudo.Admin-Members.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-pseudo.Admin-Members.png index 1c291d9ad5..03c1227419 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-pseudo.Admin-Members.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-pseudo.Admin-Members.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5399631ce7f310512b85452f95230e717a1505787e612f3078f65f9ebd604857 -size 141900 +oid sha256:fb17504e82993df630ad2cb20854e3d2aa2f85baa3192f03800fb98419ce78b0 +size 143376 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-pseudo.Invites.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-pseudo.Invites.png index 0507dca5c8..b0fb359f1f 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-pseudo.Invites.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-pseudo.Invites.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d3be505a8d77dcef1b457e847e204efff0f7e76c81af095d3cfdd88f87a2e03c -size 144426 +oid sha256:4d8d6fc490b3b7362bf326187c7526e00611bb585f3a2868bc0b1f98c6f9eaf4 +size 145856 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-pseudo.Member.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-pseudo.Member.png index c438408976..273319c189 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-pseudo.Member.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPad-pseudo.Member.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf7e90926372085ad952e03139a9d3c0815b804cc2045145d878e00de65e4671 -size 133587 +oid sha256:ebef244d49b790601115f26146d52030fdca6632385a2c225bbd554d8e51d912 +size 135046 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-en-GB.Admin-Members.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-en-GB.Admin-Members.png index 31dfb30dd6..f50fe7f486 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-en-GB.Admin-Members.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-en-GB.Admin-Members.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ebd4283903f8901a4fa2bcaca20b77a866d037581413f5908cc3a8d7dcfea03 -size 83790 +oid sha256:dc06908f037a0d2730d4a8b3b49742ddd24d72fc4ca5d0a14b1974385198ac78 +size 84815 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-en-GB.Invites.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-en-GB.Invites.png index f4b6906b35..478a37b3cf 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-en-GB.Invites.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-en-GB.Invites.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4429d4306851f0d7e6e07c216dfc1b7abb3b8380ce1d1ed53da6a54ae8220362 -size 86315 +oid sha256:9cb13eddbab510b9646fd2ee431e37208ef0d2f3b23204dce4fcf85032ba5891 +size 87183 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-en-GB.Member.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-en-GB.Member.png index bc597d215b..aa3dd7a8a9 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-en-GB.Member.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-en-GB.Member.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6a5fa320eb70ec2e1181dd063e76cd26ba9c2594c64b02058e77e9f536dfa99c -size 77966 +oid sha256:521a418127816a652a7e4d17146c3eeb1d4aa613922f11b53ef63115ef90ed1e +size 78984 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-pseudo.Admin-Members.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-pseudo.Admin-Members.png index b1197b502c..80670069f7 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-pseudo.Admin-Members.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-pseudo.Admin-Members.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c598dafaa1584f2b8886183b1d9273c9b607322b493710725feeaec2f4d4f7e6 -size 93516 +oid sha256:1d804804fc7e19802cf4d3156c34e26e2be96085fc5fe9987403940541a3e08c +size 94418 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-pseudo.Invites.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-pseudo.Invites.png index 08f2872483..ef31278aef 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-pseudo.Invites.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-pseudo.Invites.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d6ea9ff5daaa20a19ec8b822cba67eae0d8796b20a0121f33304b26c503e085d -size 96436 +oid sha256:47335b9d2db5c87e10bbbe1b441d99c9283974ac5bf0ecd716a5bf172e17af29 +size 97152 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-pseudo.Member.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-pseudo.Member.png index bb8f251df3..6a9804d901 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-pseudo.Member.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomMembersListScreen-iPhone-16-pseudo.Member.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0951e99bb5bad9c5a5be23f56e7c302b38514c0760c47ef5a39d3ed982bb38f7 -size 86447 +oid sha256:39e5aafbe8a8629ec28da856475bd1e20f83060fa4b19d543d43f58c35d9bbca +size 87331 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPad-en-GB.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPad-en-GB.1.png index 5e287266dc..102003567f 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPad-en-GB.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPad-en-GB.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d19fdc59c123919099ce464a0bb5478edb8df05e23609cd5dae1b430bcd469d1 -size 295900 +oid sha256:02b4de01b6f3291309fdef1755bf2d1a4e989cecd777766394d512ef330fbfea +size 295904 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPad-pseudo.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPad-pseudo.1.png index 092ac6fcc4..7c6a6c731b 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPad-pseudo.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPad-pseudo.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:015366f6fe40da0753b014c0be10d6f46478d36e76fef8ac0d03608c44c8665d -size 304454 +oid sha256:7be7c4f878b08ae3724587db110a3ea3ec1133f9731aca59924776ec59b54c66 +size 304445 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPhone-16-en-GB.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPhone-16-en-GB.1.png index 14f263242f..2283af443b 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPhone-16-en-GB.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPhone-16-en-GB.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e5fe32d96cc563369893c88d566260a465e5ae7f372b10f75f1cd6b9fa93877e -size 181804 +oid sha256:5236d9950c7d6179f4351b486bedb519e2afb29f65603d1ee3fea9b862936ba7 +size 181809 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPhone-16-pseudo.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPhone-16-pseudo.1.png index caf86ca422..0659bd0f44 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPhone-16-pseudo.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_roomScreen-iPhone-16-pseudo.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6332e9688b6bc74fd053be710d9fc160016ff08fe08d755420871e5a79ad6c24 -size 180191 +oid sha256:3a9027ee84e95fa1b65e7287b311a109f829302563216d57b0f4a72fbb0fcedf +size 180206 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPad-en-GB.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPad-en-GB.1.png index 5e287266dc..102003567f 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPad-en-GB.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPad-en-GB.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d19fdc59c123919099ce464a0bb5478edb8df05e23609cd5dae1b430bcd469d1 -size 295900 +oid sha256:02b4de01b6f3291309fdef1755bf2d1a4e989cecd777766394d512ef330fbfea +size 295904 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPad-pseudo.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPad-pseudo.1.png index 092ac6fcc4..7c6a6c731b 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPad-pseudo.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPad-pseudo.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:015366f6fe40da0753b014c0be10d6f46478d36e76fef8ac0d03608c44c8665d -size 304454 +oid sha256:7be7c4f878b08ae3724587db110a3ea3ec1133f9731aca59924776ec59b54c66 +size 304445 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPhone-16-en-GB.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPhone-16-en-GB.1.png index 14f263242f..2283af443b 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPhone-16-en-GB.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPhone-16-en-GB.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e5fe32d96cc563369893c88d566260a465e5ae7f372b10f75f1cd6b9fa93877e -size 181804 +oid sha256:5236d9950c7d6179f4351b486bedb519e2afb29f65603d1ee3fea9b862936ba7 +size 181809 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPhone-16-pseudo.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPhone-16-pseudo.1.png index caf86ca422..0659bd0f44 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPhone-16-pseudo.1.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_timelineView-iPhone-16-pseudo.1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6332e9688b6bc74fd053be710d9fc160016ff08fe08d755420871e5a79ad6c24 -size 180191 +oid sha256:3a9027ee84e95fa1b65e7287b311a109f829302563216d57b0f4a72fbb0fcedf +size 180206 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-en-GB.Other-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-en-GB.Other-User.png index 64d2b974e4..91d7912ff8 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-en-GB.Other-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-en-GB.Other-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c79cf23a403a1a8f7f870c5bc1b076d7db8fdc5306f8e2d570481b04f53243c -size 108340 +oid sha256:7ec0cea60e7008080e384d60dbc8de8747cd55d8740b22292b286f04f9fe61db +size 101556 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-pseudo.Other-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-pseudo.Other-User.png index 102c98513e..f37e50f45c 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-pseudo.Other-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-pseudo.Other-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:12b13a72d49eed5e18f72dc9f9fe38e030e30cce68fa3e2ff0cf30f5fbe8967d -size 110043 +oid sha256:f6883e72e65297302617486b88e8bca4e81e577aa40c888097f93099216f191f +size 102538 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-16-en-GB.Other-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-16-en-GB.Other-User.png index 3e336a7533..1131991320 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-16-en-GB.Other-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-16-en-GB.Other-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf92dab653565f100a445d2e8231e984761644436f2c9f565823f5c5730a0e28 -size 59553 +oid sha256:94fe46228c52208114afa3c511f09398921697390b27e83b1e4930eb17db5757 +size 53177 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-16-pseudo.Other-User.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-16-pseudo.Other-User.png index e711a38a4f..0659512d67 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-16-pseudo.Other-User.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-16-pseudo.Other-User.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:516372c5b8db4c73878cbce0be4015381446623317529c1a44a30fb114efd277 -size 66599 +oid sha256:62bf342ae32beb4efba3cff60e18da950cf406bbdcbd8b0e9bcca2e1906b1c06 +size 58597 From 76042c8f839f425b98009113a63c300982fb2f6f Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Mon, 17 Feb 2025 10:05:41 +0200 Subject: [PATCH 9/9] Address PR comments --- .../Sources/Other/SwiftUI/VerificationBadge.swift | 11 +++++++++++ .../Other/SwiftUI/Views/RoomHeaderView.swift | 8 ++++---- .../View/RoomMemberDetailsScreen.swift | 1 - .../Screens/RoomScreen/RoomScreenModels.swift | 2 +- .../Screens/RoomScreen/RoomScreenViewModel.swift | 13 +++++++++---- .../Screens/RoomScreen/View/RoomScreen.swift | 2 +- ElementX/Sources/Services/Client/ClientProxy.swift | 6 +----- PreviewTests/Sources/GeneratedPreviewTests.swift | 6 ++++++ .../test_verificationBadge-iPad-en-GB.1.png | 3 +++ .../test_verificationBadge-iPad-pseudo.1.png | 3 +++ .../test_verificationBadge-iPhone-16-en-GB.1.png | 3 +++ .../test_verificationBadge-iPhone-16-pseudo.1.png | 3 +++ 12 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPad-en-GB.1.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPad-pseudo.1.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPhone-16-en-GB.1.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPhone-16-pseudo.1.png diff --git a/ElementX/Sources/Other/SwiftUI/VerificationBadge.swift b/ElementX/Sources/Other/SwiftUI/VerificationBadge.swift index d110cd3aa7..17bab97c96 100644 --- a/ElementX/Sources/Other/SwiftUI/VerificationBadge.swift +++ b/ElementX/Sources/Other/SwiftUI/VerificationBadge.swift @@ -24,3 +24,14 @@ struct VerificationBadge: View { } } } + +struct VerificationBadge_Previews: PreviewProvider, TestablePreview { + static var previews: some View { + VStack(spacing: 16.0) { + VerificationBadge(verificationState: .notVerified) + VerificationBadge(verificationState: .verificationViolation) + VerificationBadge(verificationState: .verified) + } + .previewLayout(.sizeThatFits) + } +} diff --git a/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift b/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift index cdd5d6e37d..232cf2aca2 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift @@ -12,7 +12,7 @@ import SwiftUI struct RoomHeaderView: View { let roomName: String let roomAvatar: RoomAvatar - var counterpartVerificationState: UserIdentityVerificationState? + var dmRecipientVerificationState: UserIdentityVerificationState? let mediaProvider: MediaProviderProtocol? @@ -27,8 +27,8 @@ struct RoomHeaderView: View { .font(.compound.bodyLGSemibold) .accessibilityIdentifier(A11yIdentifiers.roomScreen.name) - if let counterpartVerificationState { - VerificationBadge(verificationState: counterpartVerificationState) + if let dmRecipientVerificationState { + VerificationBadge(verificationState: dmRecipientVerificationState) } } } @@ -61,7 +61,7 @@ struct RoomHeaderView_Previews: PreviewProvider, TestablePreview { roomAvatar: .room(id: "1", name: "Some Room Name", avatarURL: avatarURL), - counterpartVerificationState: verificationState, + dmRecipientVerificationState: verificationState, mediaProvider: MediaProviderMock(configuration: .init())) .padding() } diff --git a/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift b/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift index 0e30b172ec..f567d8da36 100644 --- a/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift +++ b/ElementX/Sources/Screens/RoomMemberDetailsScreen/View/RoomMemberDetailsScreen.swift @@ -115,7 +115,6 @@ struct RoomMemberDetailsScreen: View { } } - @ViewBuilder var verificationSection: some View { Section { ListRow(label: .default(title: L10n.commonVerifyUser, icon: \.lock), kind: .button { diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift index f1a5c5820c..83fe22475e 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift @@ -31,7 +31,7 @@ enum RoomScreenViewAction { struct RoomScreenViewState: BindableState { var roomTitle = "" var roomAvatar: RoomAvatar - var counterpartVerificationState: UserIdentityVerificationState? + var dmRecipientVerificationState: UserIdentityVerificationState? var lastScrollDirection: ScrollDirection? // This is used to control the banner diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index ac1438478f..a1f6b188a9 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -268,13 +268,18 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol private func updateVerificationBadge() async { guard roomProxy.isDirectOneToOneRoom, let dmRecipient = roomProxy.membersPublisher.value.first(where: { $0.userID != roomProxy.ownUserID }), - case let .success(userIdentity) = await clientProxy.userIdentity(for: dmRecipient.userID), - let userIdentity else { - state.counterpartVerificationState = .notVerified + case let .success(userIdentity) = await clientProxy.userIdentity(for: dmRecipient.userID) else { + state.dmRecipientVerificationState = .notVerified return } - state.counterpartVerificationState = userIdentity.verificationState + guard let userIdentity else { + MXLog.failure("User identity should be known at this point") + state.dmRecipientVerificationState = .notVerified + return + } + + state.dmRecipientVerificationState = userIdentity.verificationState } private func resolveIdentityPinningViolation(_ userID: String) async { diff --git a/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift b/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift index ecd5139d86..e6114ff1f0 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift @@ -204,7 +204,7 @@ struct RoomScreen: View { ToolbarItem(placement: .principal) { RoomHeaderView(roomName: roomContext.viewState.roomTitle, roomAvatar: roomContext.viewState.roomAvatar, - counterpartVerificationState: roomContext.viewState.counterpartVerificationState, + dmRecipientVerificationState: roomContext.viewState.dmRecipientVerificationState, mediaProvider: roomContext.mediaProvider) // Using a button stops it from getting truncated in the navigation bar .contentShape(.rect) diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 99352d2533..37e5a5a83b 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -1020,11 +1020,7 @@ class ClientProxy: ClientProxyProtocol { func userIdentity(for userID: String) async -> Result { do { - guard let userIdentity = try await client.encryption().userIdentity(userId: userID) else { - return .success(nil) - } - - return .success(UserIdentityProxy(userIdentity: userIdentity)) + return try await .success(client.encryption().userIdentity(userId: userID).map(UserIdentityProxy.init)) } catch { MXLog.error("Failed retrieving user identity: \(error)") return .failure(.sdkError(error)) diff --git a/PreviewTests/Sources/GeneratedPreviewTests.swift b/PreviewTests/Sources/GeneratedPreviewTests.swift index 2948145083..2d169007f4 100644 --- a/PreviewTests/Sources/GeneratedPreviewTests.swift +++ b/PreviewTests/Sources/GeneratedPreviewTests.swift @@ -1037,6 +1037,12 @@ extension PreviewTests { } } + func test_verificationBadge() async throws { + for preview in VerificationBadge_Previews._allPreviews { + try await assertSnapshots(matching: preview) + } + } + func test_videoMediaEventsTimelineView() async throws { for preview in VideoMediaEventsTimelineView_Previews._allPreviews { try await assertSnapshots(matching: preview) diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPad-en-GB.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPad-en-GB.1.png new file mode 100644 index 0000000000..05faf426d0 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPad-en-GB.1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc125492dfe1f025e9164856adc7c8c5c139c7b9f1e6ad6db977a2704e4649b3 +size 6588 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPad-pseudo.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPad-pseudo.1.png new file mode 100644 index 0000000000..05faf426d0 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPad-pseudo.1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc125492dfe1f025e9164856adc7c8c5c139c7b9f1e6ad6db977a2704e4649b3 +size 6588 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPhone-16-en-GB.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPhone-16-en-GB.1.png new file mode 100644 index 0000000000..2ebc4957c0 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPhone-16-en-GB.1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95330c60b8d668574425379be7d0f41e8e17e11c76da95afaf5f89acfb68225e +size 3755 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPhone-16-pseudo.1.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPhone-16-pseudo.1.png new file mode 100644 index 0000000000..2ebc4957c0 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/test_verificationBadge-iPhone-16-pseudo.1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95330c60b8d668574425379be7d0f41e8e17e11c76da95afaf5f89acfb68225e +size 3755