Prompt user when inviting users with uncached identities (#5331)

If the user attempts to invite someone (to a room or creating a DM) whose identity is not cached, we prompt them to make sure this was their intention.
This commit is contained in:
Skye Elliot
2026-04-14 12:51:58 +01:00
committed by GitHub
parent fe2319cada
commit 78240ebdee
45 changed files with 541 additions and 40 deletions
@@ -15,6 +15,7 @@ struct RoomMemberDetailsScreenCoordinatorParameters {
let userSession: UserSessionProtocol
let userIndicatorController: UserIndicatorControllerProtocol
let analytics: AnalyticsService
let appSettings: AppSettings
}
enum RoomMemberDetailsScreenCoordinatorAction {
@@ -39,7 +40,8 @@ final class RoomMemberDetailsScreenCoordinator: CoordinatorProtocol {
roomProxy: parameters.roomProxy,
userSession: parameters.userSession,
userIndicatorController: parameters.userIndicatorController,
analytics: parameters.analytics)
analytics: parameters.analytics,
appSettings: parameters.appSettings)
}
func start() {
@@ -79,7 +79,7 @@ struct RoomMemberDetailsScreenViewStateBindings {
var ignoreUserAlert: IgnoreUserAlertItem?
var alertInfo: AlertInfo<RoomMemberDetailsScreenAlertType>?
var inviteConfirmationUser: UserProfileProxy?
var inviteConfirmationUser: UserToInvite?
/// A media item that will be previewed with QuickLook.
var mediaPreviewItem: MediaPreviewItem?
@@ -16,6 +16,7 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro
private let userSession: UserSessionProtocol
private let userIndicatorController: UserIndicatorControllerProtocol
private let analytics: AnalyticsService
private let appSettings: AppSettings
private var actionsSubject: PassthroughSubject<RoomMemberDetailsScreenViewModelAction, Never> = .init()
@@ -29,11 +30,13 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro
roomProxy: JoinedRoomProxyProtocol,
userSession: UserSessionProtocol,
userIndicatorController: UserIndicatorControllerProtocol,
analytics: AnalyticsService) {
analytics: AnalyticsService,
appSettings: AppSettings) {
self.roomProxy = roomProxy
self.userSession = userSession
self.userIndicatorController = userIndicatorController
self.analytics = analytics
self.appSettings = appSettings
let initialViewState = RoomMemberDetailsScreenViewState(userID: userID, bindings: .init())
@@ -197,8 +200,19 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro
case .success(let roomID):
if let roomID {
actionsSubject.send(.openDirectChat(roomID: roomID))
} else if appSettings.enableKeyShareOnInvite, roomProxy.details.historySharingState != RoomHistorySharingState.hidden {
Task {
let identity = await self.userSession.clientProxy.userIdentity(for: roomMemberProxy.userID, fallBackToServer: false)
let user: UserProfileProxy = .init(userID: roomMemberProxy.userID, displayName: roomMemberProxy.displayName, avatarURL: roomMemberProxy.avatarURL)
let isUnknown = if case .success(let identity) = identity {
identity == nil
} else {
true
}
self.state.bindings.inviteConfirmationUser = .init(user: user, isUnknown: isUnknown)
}
} else {
state.bindings.inviteConfirmationUser = .init(userID: roomMemberProxy.userID, displayName: roomMemberProxy.displayName, avatarURL: roomMemberProxy.avatarURL)
state.bindings.inviteConfirmationUser = .init(user: .init(userID: roomMemberProxy.userID, displayName: roomMemberProxy.displayName, avatarURL: roomMemberProxy.avatarURL), isUnknown: false)
}
case .failure:
state.bindings.alertInfo = .init(id: .failedOpeningDirectChat)
@@ -240,6 +240,7 @@ struct RoomMemberDetailsScreen_Previews: PreviewProvider, TestablePreview {
roomProxy: roomProxyMock,
userSession: UserSessionMock(.init(clientProxy: clientProxyMock)),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
analytics: ServiceLocator.shared.analytics)
analytics: ServiceLocator.shared.analytics,
appSettings: ServiceLocator.shared.settings)
}
}