mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
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:
@@ -15,6 +15,7 @@ struct UserProfileScreenCoordinatorParameters {
|
||||
let userSession: UserSessionProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let analytics: AnalyticsService
|
||||
let appSettings: AppSettings
|
||||
}
|
||||
|
||||
enum UserProfileScreenCoordinatorAction {
|
||||
@@ -38,7 +39,8 @@ final class UserProfileScreenCoordinator: CoordinatorProtocol {
|
||||
isPresentedModally: parameters.isPresentedModally,
|
||||
userSession: parameters.userSession,
|
||||
userIndicatorController: parameters.userIndicatorController,
|
||||
analytics: parameters.analytics)
|
||||
analytics: parameters.analytics,
|
||||
appSettings: parameters.appSettings)
|
||||
}
|
||||
|
||||
func start() {
|
||||
|
||||
@@ -20,6 +20,7 @@ struct UserProfileScreenViewState: BindableState {
|
||||
let isPresentedModally: Bool
|
||||
|
||||
var userProfile: UserProfileProxy?
|
||||
var isIdentityKnown = false
|
||||
var isVerified: Bool?
|
||||
var permalink: URL?
|
||||
var dmRoomID: String?
|
||||
@@ -33,7 +34,7 @@ struct UserProfileScreenViewState: BindableState {
|
||||
|
||||
struct UserProfileScreenViewStateBindings {
|
||||
var alertInfo: AlertInfo<UserProfileScreenAlertType>?
|
||||
var inviteConfirmationUser: UserProfileProxy?
|
||||
var inviteConfirmationUser: UserToInvite?
|
||||
|
||||
/// A media item that will be previewed with QuickLook.
|
||||
var mediaPreviewItem: MediaPreviewItem?
|
||||
|
||||
@@ -16,6 +16,7 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr
|
||||
private let userSession: UserSessionProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let analytics: AnalyticsService
|
||||
private let appSettings: AppSettings
|
||||
|
||||
private var actionsSubject: PassthroughSubject<UserProfileScreenViewModelAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<UserProfileScreenViewModelAction, Never> {
|
||||
@@ -26,10 +27,12 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr
|
||||
isPresentedModally: Bool,
|
||||
userSession: UserSessionProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
analytics: AnalyticsService) {
|
||||
analytics: AnalyticsService,
|
||||
appSettings: AppSettings) {
|
||||
self.userSession = userSession
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.analytics = analytics
|
||||
self.appSettings = appSettings
|
||||
|
||||
let initialViewState = UserProfileScreenViewState(userID: userID,
|
||||
isOwnUser: userID == userSession.clientProxy.userID,
|
||||
@@ -92,8 +95,10 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr
|
||||
}
|
||||
|
||||
if case let .success(.some(identity)) = await identityResult {
|
||||
state.isIdentityKnown = true
|
||||
state.isVerified = identity.verificationState == .verified
|
||||
} else {
|
||||
state.isIdentityKnown = false
|
||||
MXLog.error("Failed to find the user's identity.")
|
||||
}
|
||||
}
|
||||
@@ -122,7 +127,18 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr
|
||||
if let roomID {
|
||||
actionsSubject.send(.openDirectChat(roomID: roomID))
|
||||
} else {
|
||||
state.bindings.inviteConfirmationUser = userProfile
|
||||
if appSettings.enableKeyShareOnInvite {
|
||||
Task {
|
||||
let isUnknown = if case let .success(identity) = await userSession.clientProxy.userIdentity(for: userProfile.userID, fallBackToServer: false) {
|
||||
identity == nil
|
||||
} else {
|
||||
true
|
||||
}
|
||||
state.bindings.inviteConfirmationUser = .init(user: userProfile, isUnknown: isUnknown)
|
||||
}
|
||||
} else {
|
||||
state.bindings.inviteConfirmationUser = .init(user: userProfile, isUnknown: false)
|
||||
}
|
||||
}
|
||||
case .failure:
|
||||
state.bindings.alertInfo = .init(id: .failedOpeningDirectChat)
|
||||
|
||||
@@ -21,8 +21,8 @@ struct UserProfileScreen: View {
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar { toolbar }
|
||||
.alert(item: $context.alertInfo)
|
||||
.sheet(item: $context.inviteConfirmationUser) { user in
|
||||
SendInviteConfirmationView(userToInvite: user,
|
||||
.sheet(item: $context.inviteConfirmationUser) { userToInvite in
|
||||
SendInviteConfirmationView(userToInvite: userToInvite,
|
||||
mediaProvider: context.mediaProvider) {
|
||||
context.send(viewAction: .createDirectChat)
|
||||
}
|
||||
@@ -147,6 +147,7 @@ struct UserProfileScreen_Previews: PreviewProvider, TestablePreview {
|
||||
isPresentedModally: false,
|
||||
userSession: UserSessionMock(.init(clientProxy: clientProxyMock)),
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
analytics: ServiceLocator.shared.analytics)
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user