mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user