mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
User verification state indicators (#3793)
* Introduce a `UserIdentityProxy` and have it combine upstream methods into an easy to digest `UserIdentityVerificationState`. Use it in a dedicated `VerificationBadge` UI component * Show a DMs counterpart verification state in the room header * Show a warning on the room details `People` entry when there are identity verification state violations on any of the members. * Show verification badges in the room member list * Show a withdraw verification section on the room member details for users that have pinning violations. * 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. * Update preview test snapshots
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -95,7 +93,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.")
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -137,13 +123,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(UserIdentitySDKMock(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,
|
||||
|
||||
Reference in New Issue
Block a user