Add user verification and verification state violation badges (#4392)

* Move `observeRoomMemberIdentityStateChange` and associated classes to `libs:matrixui` module so they can be reused

* Add `EncryptionService.getUserIdentity` method to retrieve not only if the user is verified or not, but in which state they are

* Fix `IdentityChangePresenter` after the previous changes

* Fix `withFakeLifecycleOwner` and add `testWithLifecycleOwner` helper

* Display verified badge in DM top app bar when possible

* Display a verification violation warning icon next to the 'People' item in room details screen

* Display either a verified badge or a verification violation warning icon next to the room members in the room member list screen

* Display either a verified badge or a verification violation warning and withdraw verification button in the room member profile.

Generic user profiles won't display verification state anymore since we can't easily track changes in it.

* Add preview for room member details screen with verification violation identity state

* Add verified and violation badge to the `Profile` list item in room details screen

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
Jorge Martin Espinosa 2025-03-12 12:22:53 +01:00 committed by GitHub
parent b0e6b50c79
commit fd50ce4daf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
75 changed files with 889 additions and 364 deletions

View file

@ -18,6 +18,7 @@ import io.element.android.libraries.matrix.api.encryption.EnableRecoveryProgress
import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.encryption.IdentityResetHandle
import io.element.android.libraries.matrix.api.encryption.RecoveryState
import io.element.android.libraries.matrix.api.encryption.identity.IdentityState
import io.element.android.libraries.matrix.api.sync.SyncState
import io.element.android.libraries.matrix.impl.sync.RustSyncService
import kotlinx.coroutines.CoroutineScope
@ -202,18 +203,29 @@ internal class RustEncryptionService(
}
override suspend fun isUserVerified(userId: UserId): Result<Boolean> = runCatching {
getUserIdentity(userId).isVerified()
getUserIdentityInternal(userId).isVerified()
}
override suspend fun pinUserIdentity(userId: UserId): Result<Unit> = runCatching {
getUserIdentity(userId).pin()
getUserIdentityInternal(userId).pin()
}
override suspend fun withdrawVerification(userId: UserId): Result<Unit> = runCatching {
getUserIdentity(userId).withdrawVerification()
getUserIdentityInternal(userId).withdrawVerification()
}
private suspend fun getUserIdentity(userId: UserId): UserIdentity {
override suspend fun getUserIdentity(userId: UserId): Result<IdentityState?> = runCatching {
val identity = getUserIdentityInternal(userId)
val isVerified = identity.isVerified()
when {
identity.hasVerificationViolation() -> IdentityState.VerificationViolation
isVerified -> IdentityState.Verified
!isVerified -> IdentityState.Pinned
else -> null
}
}
suspend fun getUserIdentityInternal(userId: UserId): UserIdentity {
return service.userIdentity(
userId = userId.value,
// requestFromHomeserverIfNeeded = true,