From f0645154ca2d6cbdadbc57ea6b36ae9518dc1012 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet <> Date: Tue, 6 Jun 2023 15:01:43 +0200 Subject: [PATCH 1/4] =?UTF-8?q?Suppression=20des=20r=C3=A9f=C3=A9rences=20?= =?UTF-8?q?InviteService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Home/AllChats/AllChatsCoordinator.swift | 120 +++--- Riot/Modules/TabBar/TabBarCoordinator.swift | 100 ++--- Tchap/Managers/Invite/InviteService.swift | 370 +++++++++--------- Tchap/Managers/Invite/InviteServiceType.swift | 50 +-- 4 files changed, 321 insertions(+), 319 deletions(-) diff --git a/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift b/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift index 14e040114c..9e9646559b 100644 --- a/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift +++ b/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift @@ -81,7 +81,7 @@ class AllChatsCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { private var indicators = [UserIndicator]() private var signOutFlowPresenter: SignOutFlowPresenter? // Tchap: Add invite service for user invitation - private var inviteService: InviteServiceType? +// private var inviteService: InviteServiceType? private var errorPresenter: ErrorPresenter? private weak var currentAlertController: UIAlertController? @@ -360,7 +360,7 @@ class AllChatsCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { !UserService.isExternalUser(for: userID) { subMenuActions.append(UIAction(title: TchapL10n.sideMenuActionInviteFriends, image: UIImage(systemName: "square.and.arrow.up.fill")) { [weak self] action in guard let self = self else { return } - self.showInviteFriends(from: self.avatarMenuButton) + self.allChatsViewController.startChat() }) } } @@ -644,15 +644,15 @@ class AllChatsCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { // } private func showInviteFriends(from sourceView: UIView?) { - // Tchap: Use Tchap specific mechanism. - promptUserToFillAnEmailToInvite { [weak self] email in - self?.sendEmailInvite(to: email) - } - -// let myUserId = self.parameters.userSessionsService.mainUserSession?.userId ?? "" -// -// let inviteFriendsPresenter = InviteFriendsPresenter() -// inviteFriendsPresenter.present(for: myUserId, from: self.navigationRouter.toPresentable(), sourceView: sourceView, animated: true) +// // Tchap: Use Tchap specific mechanism. +// promptUserToFillAnEmailToInvite { [weak self] email in +// self?.sendEmailInvite(to: email) +// } +// +//// let myUserId = self.parameters.userSessionsService.mainUserSession?.userId ?? "" +//// +//// let inviteFriendsPresenter = InviteFriendsPresenter() +//// inviteFriendsPresenter.present(for: myUserId, from: self.navigationRouter.toPresentable(), sourceView: sourceView, animated: true) } private func showBugReport() { @@ -911,55 +911,55 @@ extension AllChatsCoordinator { } private func sendEmailInvite(to email: String) { - guard let session = self.currentMatrixSession else { return } - if self.inviteService == nil { - self.inviteService = InviteService(session: session) - } - guard let inviteService = self.inviteService else { return } - - self.activityIndicatorPresenter.presentActivityIndicator(on: self.navigationRouter.toPresentable().view, animated: true) - inviteService.sendEmailInvite(to: email) { [weak self] (response) in - guard let sself = self else { - return - } - - sself.activityIndicatorPresenter.removeCurrentActivityIndicator(animated: true) - switch response { - case .success(let result): - var message: String - var discoveredUserID: String? - switch result { - case .inviteHasBeenSent(roomID: _): - message = TchapL10n.inviteSendingSucceeded - case .inviteAlreadySent(roomID: _): - message = TchapL10n.inviteAlreadySentByEmail(email) - case .inviteIgnoredForDiscoveredUser(userID: let userID): - discoveredUserID = userID - message = TchapL10n.inviteNotSentForDiscoveredUser - case .inviteIgnoredForUnauthorizedEmail: - message = TchapL10n.inviteNotSentForUnauthorizedEmail(email) - } - - sself.currentAlertController?.dismiss(animated: false) - - let alert = UIAlertController(title: TchapL10n.inviteInformationTitle, message: message, preferredStyle: .alert) - - let okTitle = VectorL10n.ok - let okAction = UIAlertAction(title: okTitle, style: .default, handler: { action in - if let userID = discoveredUserID { - // Open the discussion - AppDelegate.theDelegate().startDirectChat(withUserId: userID, completion: nil) - } - }) - alert.addAction(okAction) - sself.currentAlertController = alert - - sself.navigationRouter.toPresentable().present(alert, animated: true, completion: nil) - case .failure(let error): - let errorPresentable = sself.inviteErrorPresentable(from: error) - sself.errorPresenter?.present(errorPresentable: errorPresentable, animated: true) - } - } +// guard let session = self.currentMatrixSession else { return } +// if self.inviteService == nil { +// self.inviteService = InviteService(session: session) +// } +// guard let inviteService = self.inviteService else { return } +// +// self.activityIndicatorPresenter.presentActivityIndicator(on: self.navigationRouter.toPresentable().view, animated: true) +// inviteService.sendEmailInvite(to: email) { [weak self] (response) in +// guard let sself = self else { +// return +// } +// +// sself.activityIndicatorPresenter.removeCurrentActivityIndicator(animated: true) +// switch response { +// case .success(let result): +// var message: String +// var discoveredUserID: String? +// switch result { +// case .inviteHasBeenSent(roomID: _): +// message = TchapL10n.inviteSendingSucceeded +// case .inviteAlreadySent(roomID: _): +// message = TchapL10n.inviteAlreadySentByEmail(email) +// case .inviteIgnoredForDiscoveredUser(userID: let userID): +// discoveredUserID = userID +// message = TchapL10n.inviteNotSentForDiscoveredUser +// case .inviteIgnoredForUnauthorizedEmail: +// message = TchapL10n.inviteNotSentForUnauthorizedEmail(email) +// } +// +// sself.currentAlertController?.dismiss(animated: false) +// +// let alert = UIAlertController(title: TchapL10n.inviteInformationTitle, message: message, preferredStyle: .alert) +// +// let okTitle = VectorL10n.ok +// let okAction = UIAlertAction(title: okTitle, style: .default, handler: { action in +// if let userID = discoveredUserID { +// // Open the discussion +// AppDelegate.theDelegate().startDirectChat(withUserId: userID, completion: nil) +// } +// }) +// alert.addAction(okAction) +// sself.currentAlertController = alert +// +// sself.navigationRouter.toPresentable().present(alert, animated: true, completion: nil) +// case .failure(let error): +// let errorPresentable = sself.inviteErrorPresentable(from: error) +// sself.errorPresenter?.present(errorPresentable: errorPresentable, animated: true) +// } +// } } private func inviteErrorPresentable(from error: Error) -> ErrorPresentable { diff --git a/Riot/Modules/TabBar/TabBarCoordinator.swift b/Riot/Modules/TabBar/TabBarCoordinator.swift index f2e916abca..9219807277 100644 --- a/Riot/Modules/TabBar/TabBarCoordinator.swift +++ b/Riot/Modules/TabBar/TabBarCoordinator.swift @@ -71,7 +71,7 @@ final class TabBarCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { private var indicators = [UserIndicator]() // Tchap: Add invite service for user invitation - private var inviteService: InviteServiceType? +// private var inviteService: InviteServiceType? private var errorPresenter: ErrorPresenter? private weak var currentAlertController: UIAlertController? @@ -1020,55 +1020,55 @@ extension TabBarCoordinator { } private func sendEmailInvite(to email: String) { - guard let session = self.currentMatrixSession else { return } - if self.inviteService == nil { - self.inviteService = InviteService(session: session) - } - guard let inviteService = self.inviteService else { return } - - self.activityIndicatorPresenter.presentActivityIndicator(on: masterTabBarController.view, animated: true) - inviteService.sendEmailInvite(to: email) { [weak self] (response) in - guard let sself = self else { - return - } - - sself.activityIndicatorPresenter.removeCurrentActivityIndicator(animated: true) - switch response { - case .success(let result): - var message: String - var discoveredUserID: String? - switch result { - case .inviteHasBeenSent(roomID: _): - message = TchapL10n.inviteSendingSucceeded - case .inviteAlreadySent(roomID: _): - message = TchapL10n.inviteAlreadySentByEmail(email) - case .inviteIgnoredForDiscoveredUser(userID: let userID): - discoveredUserID = userID - message = TchapL10n.inviteNotSentForDiscoveredUser - case .inviteIgnoredForUnauthorizedEmail: - message = TchapL10n.inviteNotSentForUnauthorizedEmail(email) - } - - sself.currentAlertController?.dismiss(animated: false) - - let alert = UIAlertController(title: TchapL10n.inviteInformationTitle, message: message, preferredStyle: .alert) - - let okTitle = VectorL10n.ok - let okAction = UIAlertAction(title: okTitle, style: .default, handler: { action in - if let userID = discoveredUserID { - // Open the discussion - AppDelegate.theDelegate().startDirectChat(withUserId: userID, completion: nil) - } - }) - alert.addAction(okAction) - sself.currentAlertController = alert - - sself.masterTabBarController.present(alert, animated: true, completion: nil) - case .failure(let error): - let errorPresentable = sself.inviteErrorPresentable(from: error) - sself.errorPresenter?.present(errorPresentable: errorPresentable, animated: true) - } - } +// guard let session = self.currentMatrixSession else { return } +// if self.inviteService == nil { +// self.inviteService = InviteService(session: session) +// } +// guard let inviteService = self.inviteService else { return } +// +// self.activityIndicatorPresenter.presentActivityIndicator(on: masterTabBarController.view, animated: true) +// inviteService.sendEmailInvite(to: email) { [weak self] (response) in +// guard let sself = self else { +// return +// } +// +// sself.activityIndicatorPresenter.removeCurrentActivityIndicator(animated: true) +// switch response { +// case .success(let result): +// var message: String +// var discoveredUserID: String? +// switch result { +// case .inviteHasBeenSent(roomID: _): +// message = TchapL10n.inviteSendingSucceeded +// case .inviteAlreadySent(roomID: _): +// message = TchapL10n.inviteAlreadySentByEmail(email) +// case .inviteIgnoredForDiscoveredUser(userID: let userID): +// discoveredUserID = userID +// message = TchapL10n.inviteNotSentForDiscoveredUser +// case .inviteIgnoredForUnauthorizedEmail: +// message = TchapL10n.inviteNotSentForUnauthorizedEmail(email) +// } +// +// sself.currentAlertController?.dismiss(animated: false) +// +// let alert = UIAlertController(title: TchapL10n.inviteInformationTitle, message: message, preferredStyle: .alert) +// +// let okTitle = VectorL10n.ok +// let okAction = UIAlertAction(title: okTitle, style: .default, handler: { action in +// if let userID = discoveredUserID { +// // Open the discussion +// AppDelegate.theDelegate().startDirectChat(withUserId: userID, completion: nil) +// } +// }) +// alert.addAction(okAction) +// sself.currentAlertController = alert +// +// sself.masterTabBarController.present(alert, animated: true, completion: nil) +// case .failure(let error): +// let errorPresentable = sself.inviteErrorPresentable(from: error) +// sself.errorPresenter?.present(errorPresentable: errorPresentable, animated: true) +// } +// } } private func inviteErrorPresentable(from error: Error) -> ErrorPresentable { diff --git a/Tchap/Managers/Invite/InviteService.swift b/Tchap/Managers/Invite/InviteService.swift index 062bf568e7..3c9950e29e 100644 --- a/Tchap/Managers/Invite/InviteService.swift +++ b/Tchap/Managers/Invite/InviteService.swift @@ -14,187 +14,189 @@ limitations under the License. */ -import Foundation -import MatrixSDK - -enum InviteServiceError: Error { - case unknown -} - -/// `InviteService` is used to invite someone to join Tchap -final class InviteService: InviteServiceType { - - // MARK: Private - private let session: MXSession - - private let discussionFinder: DiscussionFinderType - private let userService: UserServiceType - private let roomService: RoomServiceType - - private var roomInProcess: MXRoom? - - // MARK: - Public - init(session: MXSession) { - self.session = session - self.discussionFinder = DiscussionFinder(session: session) - self.userService = UserService(session: session) - self.roomService = RoomService(session: session) - } - - func sendEmailInvite(to email: String, completion: @escaping (MXResponse) -> Void) { - // Start the invite process by checking whether a Tchap account has been created for this email. - self.discoverUser(with: email, completion: { [weak self] (response) in - switch response { - case .success(let result): - switch result { - case .bound(let userID): - completion(.success(.inviteIgnoredForDiscoveredUser(userID: userID))) - case .unbound: - // Pursue the invite process by checking whether an invite has been already sent - self?.discussionFinder.getDiscussionIdentifier(for: email) { [weak self] (response) in - guard let self = self else { - return - } - - switch response { - case .success(let result): - switch result { - case .joinedDiscussion(let roomID): - // There is already a discussion with this email - // We do not re-invite the NoTchapUser except if - // the email is bound to the external instance (for which the invites may expire). - self.userService.isEmailBoundToTheExternalHost(email) { [weak self] (response) in - switch response { - case .success(let isExternal): - if isExternal { - // Revoke the pending invite and leave this empty discussion, we will invite again this email. - // We don't have a way for the moment to check if the invite expired or not... - self?.revokePendingInviteAndLeave(roomID) { [weak self] (response) in - switch response { - case .success: - // Send the new invite - self?.createDiscussion(with: email, completion: completion) - case .failure: - // Ignore the error, notify the user that the invite has been already sent - completion(.success(.inviteAlreadySent(roomID: roomID))) - } - } - } else { - // Notify the user that the invite has been already sent - completion(.success(.inviteAlreadySent(roomID: roomID))) - } - case .failure: - // Ignore the error, notify the user that the invite has been already sent - completion(.success(.inviteAlreadySent(roomID: roomID))) - } - } - case .noDiscussion: - // Send the invite if the email is authorized - self.createDiscussion(with: email, completion: completion) - default: - break - } - case .failure(let error): - MXLog.debug("[InviteService] sendEmailInvite failed") - completion(MXResponse.failure(error)) - } - } - } - case .failure(let error): - completion(MXResponse.failure(error)) - } - }) - } - - // MARK: - Private - - // Check whether a Tchap account has been created for this email. The closure returns a nil identifier when no account exists. - private func discoverUser(with email: String, completion: @escaping (MXResponse) -> Void) { - guard let identityService = self.session.identityService else { - MXLog.debug("[InviteService] discoverUser failed") - completion(MXResponse.failure(InviteServiceError.unknown)) - return - } - let pid = MX3PID(medium: .email, address: email) - _ = identityService.lookup3PIDs([pid]) { response in - if let responseValue = response.value?[pid] { - completion(MXResponse.success(.bound(userID: responseValue))) - } else { - completion(MXResponse.success(.unbound)) - } - } - } - - private func createDiscussion(with email: String, completion: @escaping (MXResponse) -> Void) { - self.userService.isEmailAuthorized(email) { [weak self] (response) in - switch response { - case .success(let isAuthorized): - if isAuthorized { - guard let identityServer = self?.session.matrixRestClient.identityServer ?? self?.session.matrixRestClient.homeserver, - let identityServerURL = URL(string: identityServer), - let identityServerHost = identityServerURL.host else { - return - } - - let thirdPartyId = MXInvite3PID() - thirdPartyId.medium = MX3PID.Medium.email.identifier - thirdPartyId.address = email - thirdPartyId.identityServer = identityServerHost - - _ = self?.roomService.createDiscussionWithThirdPartyID(thirdPartyId, completion: { (response) in - switch response { - case .success(let roomID): - completion(.success(.inviteHasBeenSent(roomID: roomID))) - case .failure(let error): - MXLog.debug("[InviteService] createDiscussion failed") - completion(MXResponse.failure(error)) - } - }) - } else { - completion(.success(.inviteIgnoredForUnauthorizedEmail)) - } - - case .failure(let error): - completion(MXResponse.failure(error)) - } - } - } - - private func revokePendingInviteAndLeave(_ roomID: String, completion: @escaping (MXResponse) -> Void) { - guard let room = self.session.room(withRoomId: roomID) else { - MXLog.debug("[InviteService] unable to revoke invite") - completion(.failure(InviteServiceError.unknown)) - return - } - - roomInProcess = room - room.state { [weak self] roomState in - guard let self = self else { - return - } - - if let thirdPartyInvite = roomState?.thirdPartyInvites?.first, - let token = thirdPartyInvite.token { - self.roomInProcess?.sendStateEvent(.roomThirdPartyInvite, content: [:], stateKey: token) { [weak self] (response) in - guard let self = self else { - return - } - - switch response { - case .success: - // Leave now the room - self.session.leaveRoom(roomID, completion: completion) - case .failure(let error): - completion(.failure(error)) - } - - self.roomInProcess = nil - } - } else { - MXLog.debug("[InviteService] unable to revoke invite (no pending invite)") - self.session.leaveRoom(roomID, completion: completion) - self.roomInProcess = nil - } - } - } -} +//import Foundation +//import MatrixSDK +// +//enum InviteServiceError: Error { +// case unknown +//} +// +///// `InviteService` is used to invite someone to join Tchap +//final class InviteService: InviteServiceType { +// +// // MARK: Private +// private let session: MXSession +// +// private let discussionFinder: DiscussionFinderType +// private let userService: UserServiceType +// private let roomService: RoomServiceType +// +// private var roomInProcess: MXRoom? +// +// // MARK: - Public +// init(session: MXSession) { +// self.session = session +// self.discussionFinder = DiscussionFinder(session: session) +// self.userService = UserService(session: session) +// self.roomService = RoomService(session: session) +// } +// +// func sendEmailInvite(to email: String, completion: @escaping (MXResponse) -> Void) { +// // Start the invite process by checking whether a Tchap account has been created for this email. +// self.discoverUser(with: email, completion: { [weak self] (response) in +// switch response { +// case .success(let result): +// switch result { +// case .bound(let userID): +// completion(.success(.inviteIgnoredForDiscoveredUser(userID: userID))) +// case .unbound: +// // Pursue the invite process by checking whether an invite has been already sent +// self?.discussionFinder.getDiscussionIdentifier(for: email) { [weak self] (response) in +// guard let self = self else { +// return +// } +// +// switch response { +// case .success(let result): +// switch result { +// case .joinedDiscussion(let roomID): +// // There is already a discussion with this email +// // We do not re-invite the NoTchapUser except if +// // the email is bound to the external instance (for which the invites may expire). +// self.userService.isEmailBoundToTheExternalHost(email) { [weak self] (response) in +// switch response { +// case .success(let isExternal): +// if isExternal { +// // Revoke the pending invite and leave this empty discussion, we will invite again this email. +// // We don't have a way for the moment to check if the invite expired or not... +// self?.revokePendingInviteAndLeave(roomID) { [weak self] (response) in +// switch response { +// case .success: +// // Send the new invite +// self?.createDiscussion(with: email, completion: completion) +// case .failure: +// // Ignore the error, notify the user that the invite has been already sent +// completion(.success(.inviteAlreadySent(roomID: roomID))) +// } +// } +// } else { +// // Notify the user that the invite has been already sent +// completion(.success(.inviteAlreadySent(roomID: roomID))) +// } +// case .failure: +// // Ignore the error, notify the user that the invite has been already sent +// completion(.success(.inviteAlreadySent(roomID: roomID))) +// } +// } +// case .noDiscussion: +// // Send the invite if the email is authorized +// self.createDiscussion(with: email, completion: completion) +// default: +// break +// } +// case .failure(let error): +// MXLog.debug("[InviteService] sendEmailInvite failed") +// completion(MXResponse.failure(error)) +// } +// } +// } +// case .failure(let error): +// completion(MXResponse.failure(error)) +// } +// }) +// } +// +// // MARK: - Private +// +// // Check whether a Tchap account has been created for this email. The closure returns a nil identifier when no account exists. +// private func discoverUser(with email: String, completion: @escaping (MXResponse) -> Void) { +// guard let identityService = self.session.identityService else { +// MXLog.debug("[InviteService] discoverUser failed") +// completion(MXResponse.failure(InviteServiceError.unknown)) +// return +// } +// let pid = MX3PID(medium: .email, address: email) +// _ = identityService.lookup3PIDs([pid]) { response in +// if let responseValue = response.value?[pid] { +// completion(MXResponse.success(.bound(userID: responseValue))) +// } else { +// completion(MXResponse.success(.unbound)) +// } +// } +// } +// +// private func createDiscussion(with email: String, completion: @escaping (MXResponse) -> Void) { +// self.userService.isEmailAuthorized(email) { [weak self] (response) in +// switch response { +// case .success(let isAuthorized): +// if isAuthorized { +// guard +// let matrixRestClient = self?.session.matrixRestClient, +// let identityServer = matrixRestClient.identityServer ?? matrixRestClient.homeserver, +// let identityServerURL = URL(string: identityServer), +// let identityServerHost = identityServerURL.host else { +// return +// } +// +// let thirdPartyId = MXInvite3PID() +// thirdPartyId.medium = MX3PID.Medium.email.identifier +// thirdPartyId.address = email +// thirdPartyId.identityServer = identityServerHost +// +// _ = self?.roomService.createDiscussionWithThirdPartyID(thirdPartyId, completion: { (response) in +// switch response { +// case .success(let roomID): +// completion(.success(.inviteHasBeenSent(roomID: roomID))) +// case .failure(let error): +// MXLog.debug("[InviteService] createDiscussion failed") +// completion(MXResponse.failure(error)) +// } +// }) +// } else { +// completion(.success(.inviteIgnoredForUnauthorizedEmail)) +// } +// +// case .failure(let error): +// completion(MXResponse.failure(error)) +// } +// } +// } +// +// private func revokePendingInviteAndLeave(_ roomID: String, completion: @escaping (MXResponse) -> Void) { +// guard let room = self.session.room(withRoomId: roomID) else { +// MXLog.debug("[InviteService] unable to revoke invite") +// completion(.failure(InviteServiceError.unknown)) +// return +// } +// +// roomInProcess = room +// room.state { [weak self] roomState in +// guard let self = self else { +// return +// } +// +// if let thirdPartyInvite = roomState?.thirdPartyInvites?.first, +// let token = thirdPartyInvite.token { +// self.roomInProcess?.sendStateEvent(.roomThirdPartyInvite, content: [:], stateKey: token) { [weak self] (response) in +// guard let self = self else { +// return +// } +// +// switch response { +// case .success: +// // Leave now the room +// self.session.leaveRoom(roomID, completion: completion) +// case .failure(let error): +// completion(.failure(error)) +// } +// +// self.roomInProcess = nil +// } +// } else { +// MXLog.debug("[InviteService] unable to revoke invite (no pending invite)") +// self.session.leaveRoom(roomID, completion: completion) +// self.roomInProcess = nil +// } +// } +// } +//} diff --git a/Tchap/Managers/Invite/InviteServiceType.swift b/Tchap/Managers/Invite/InviteServiceType.swift index ca3c5ec147..9e36b5f943 100644 --- a/Tchap/Managers/Invite/InviteServiceType.swift +++ b/Tchap/Managers/Invite/InviteServiceType.swift @@ -16,28 +16,28 @@ import Foundation -/// List the different result cases -enum InviteServiceResult { - case inviteHasBeenSent(roomID: String) - case inviteAlreadySent(roomID: String) - case inviteIgnoredForDiscoveredUser(userID: String) - case inviteIgnoredForUnauthorizedEmail -} - - -/// List the different discover user result cases -enum InviteServiceDiscoverUserResult { - case bound(userID: String) - case unbound -} - -/// Protocol describing a service used to invite someone to join Tchap. -protocol InviteServiceType { - - /// Invite a contact by inviting him in a direct chat (if this is not already done). - /// - /// - Parameters: - /// - email: an email address. - /// - completion: A closure called when the operation complete. See InviteServiceResult values. - func sendEmailInvite(to email: String, completion: @escaping (MXResponse) -> Void) -} +///// List the different result cases +//enum { +// case inviteHasBeenSent(roomID: String) +// case inviteAlreadySent(roomID: String) +// case inviteIgnoredForDiscoveredUser(userID: String) +// case inviteIgnoredForUnauthorizedEmail +//} +// +// +///// List the different discover user result cases +//enum InviteServiceDiscoverUserResult { +// case bound(userID: String) +// case unbound +//} +// +///// Protocol describing a service used to invite someone to join Tchap. +//protocol InviteServiceType { +// +// /// Invite a contact by inviting him in a direct chat (if this is not already done). +// /// +// /// - Parameters: +// /// - email: an email address. +// /// - completion: A closure called when the operation complete. See InviteServiceResult values. +// func sendEmailInvite(to email: String, completion: @escaping (MXResponse) -> Void) +//} From 0a3580266a83fbee0c3842eef4e50a490ebc42d9 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 10 Oct 2023 18:35:02 +0200 Subject: [PATCH 2/4] Add changelog --- changelog.d/837.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/837.bugfix diff --git a/changelog.d/837.bugfix b/changelog.d/837.bugfix new file mode 100644 index 0000000000..3c6e5c59d5 --- /dev/null +++ b/changelog.d/837.bugfix @@ -0,0 +1 @@ +Réparer la fonctionnalité “Inviter à rejoindre Tchap” From c7cf6e77ac8be83672967da9c8eedd52cabbade8 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Wed, 11 Oct 2023 19:32:32 +0200 Subject: [PATCH 3/4] Remove Tchap specific code or module --- .../Home/AllChats/AllChatsCoordinator.swift | 81 ------- Riot/Modules/TabBar/TabBarCoordinator.swift | 71 +----- Tchap/Managers/Invite/InviteService.swift | 202 ------------------ Tchap/Managers/Invite/InviteServiceType.swift | 43 ---- 4 files changed, 1 insertion(+), 396 deletions(-) delete mode 100644 Tchap/Managers/Invite/InviteService.swift delete mode 100644 Tchap/Managers/Invite/InviteServiceType.swift diff --git a/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift b/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift index 9e9646559b..873a6ad985 100644 --- a/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift +++ b/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift @@ -80,8 +80,6 @@ class AllChatsCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { private var indicators = [UserIndicator]() private var signOutFlowPresenter: SignOutFlowPresenter? - // Tchap: Add invite service for user invitation -// private var inviteService: InviteServiceType? private var errorPresenter: ErrorPresenter? private weak var currentAlertController: UIAlertController? @@ -643,18 +641,6 @@ class AllChatsCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { // return versionCheckCoordinator // } - private func showInviteFriends(from sourceView: UIView?) { -// // Tchap: Use Tchap specific mechanism. -// promptUserToFillAnEmailToInvite { [weak self] email in -// self?.sendEmailInvite(to: email) -// } -// -//// let myUserId = self.parameters.userSessionsService.mainUserSession?.userId ?? "" -//// -//// let inviteFriendsPresenter = InviteFriendsPresenter() -//// inviteFriendsPresenter.present(for: myUserId, from: self.navigationRouter.toPresentable(), sourceView: sourceView, animated: true) - } - private func showBugReport() { let bugReportViewController = BugReportViewController() @@ -909,73 +895,6 @@ extension AllChatsCoordinator { self.navigationRouter.toPresentable().present(alertController, animated: true) } - - private func sendEmailInvite(to email: String) { -// guard let session = self.currentMatrixSession else { return } -// if self.inviteService == nil { -// self.inviteService = InviteService(session: session) -// } -// guard let inviteService = self.inviteService else { return } -// -// self.activityIndicatorPresenter.presentActivityIndicator(on: self.navigationRouter.toPresentable().view, animated: true) -// inviteService.sendEmailInvite(to: email) { [weak self] (response) in -// guard let sself = self else { -// return -// } -// -// sself.activityIndicatorPresenter.removeCurrentActivityIndicator(animated: true) -// switch response { -// case .success(let result): -// var message: String -// var discoveredUserID: String? -// switch result { -// case .inviteHasBeenSent(roomID: _): -// message = TchapL10n.inviteSendingSucceeded -// case .inviteAlreadySent(roomID: _): -// message = TchapL10n.inviteAlreadySentByEmail(email) -// case .inviteIgnoredForDiscoveredUser(userID: let userID): -// discoveredUserID = userID -// message = TchapL10n.inviteNotSentForDiscoveredUser -// case .inviteIgnoredForUnauthorizedEmail: -// message = TchapL10n.inviteNotSentForUnauthorizedEmail(email) -// } -// -// sself.currentAlertController?.dismiss(animated: false) -// -// let alert = UIAlertController(title: TchapL10n.inviteInformationTitle, message: message, preferredStyle: .alert) -// -// let okTitle = VectorL10n.ok -// let okAction = UIAlertAction(title: okTitle, style: .default, handler: { action in -// if let userID = discoveredUserID { -// // Open the discussion -// AppDelegate.theDelegate().startDirectChat(withUserId: userID, completion: nil) -// } -// }) -// alert.addAction(okAction) -// sself.currentAlertController = alert -// -// sself.navigationRouter.toPresentable().present(alert, animated: true, completion: nil) -// case .failure(let error): -// let errorPresentable = sself.inviteErrorPresentable(from: error) -// sself.errorPresenter?.present(errorPresentable: errorPresentable, animated: true) -// } -// } - } - - private func inviteErrorPresentable(from error: Error) -> ErrorPresentable { - let errorTitle = TchapL10n.inviteSendingFailedTitle - let errorMessage: String - - let nsError = error as NSError - - if let message = nsError.userInfo[NSLocalizedDescriptionKey] as? String { - errorMessage = message - } else { - errorMessage = TchapL10n.errorMessageDefault - } - - return ErrorPresentableImpl(title: errorTitle, message: errorMessage) - } } // Tchap: Add delegate for Room Preview diff --git a/Riot/Modules/TabBar/TabBarCoordinator.swift b/Riot/Modules/TabBar/TabBarCoordinator.swift index 9219807277..198ca5e6ae 100644 --- a/Riot/Modules/TabBar/TabBarCoordinator.swift +++ b/Riot/Modules/TabBar/TabBarCoordinator.swift @@ -70,8 +70,6 @@ final class TabBarCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { } private var indicators = [UserIndicator]() - // Tchap: Add invite service for user invitation -// private var inviteService: InviteServiceType? private var errorPresenter: ErrorPresenter? private weak var currentAlertController: UIAlertController? @@ -240,7 +238,7 @@ final class TabBarCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { func presentInvitePeople() { promptUserToFillAnEmailToInvite { [weak self] email in - self?.sendEmailInvite(to: email) + } } @@ -1018,73 +1016,6 @@ extension TabBarCoordinator { masterTabBarController.present(alertController, animated: true) } - - private func sendEmailInvite(to email: String) { -// guard let session = self.currentMatrixSession else { return } -// if self.inviteService == nil { -// self.inviteService = InviteService(session: session) -// } -// guard let inviteService = self.inviteService else { return } -// -// self.activityIndicatorPresenter.presentActivityIndicator(on: masterTabBarController.view, animated: true) -// inviteService.sendEmailInvite(to: email) { [weak self] (response) in -// guard let sself = self else { -// return -// } -// -// sself.activityIndicatorPresenter.removeCurrentActivityIndicator(animated: true) -// switch response { -// case .success(let result): -// var message: String -// var discoveredUserID: String? -// switch result { -// case .inviteHasBeenSent(roomID: _): -// message = TchapL10n.inviteSendingSucceeded -// case .inviteAlreadySent(roomID: _): -// message = TchapL10n.inviteAlreadySentByEmail(email) -// case .inviteIgnoredForDiscoveredUser(userID: let userID): -// discoveredUserID = userID -// message = TchapL10n.inviteNotSentForDiscoveredUser -// case .inviteIgnoredForUnauthorizedEmail: -// message = TchapL10n.inviteNotSentForUnauthorizedEmail(email) -// } -// -// sself.currentAlertController?.dismiss(animated: false) -// -// let alert = UIAlertController(title: TchapL10n.inviteInformationTitle, message: message, preferredStyle: .alert) -// -// let okTitle = VectorL10n.ok -// let okAction = UIAlertAction(title: okTitle, style: .default, handler: { action in -// if let userID = discoveredUserID { -// // Open the discussion -// AppDelegate.theDelegate().startDirectChat(withUserId: userID, completion: nil) -// } -// }) -// alert.addAction(okAction) -// sself.currentAlertController = alert -// -// sself.masterTabBarController.present(alert, animated: true, completion: nil) -// case .failure(let error): -// let errorPresentable = sself.inviteErrorPresentable(from: error) -// sself.errorPresenter?.present(errorPresentable: errorPresentable, animated: true) -// } -// } - } - - private func inviteErrorPresentable(from error: Error) -> ErrorPresentable { - let errorTitle = TchapL10n.inviteSendingFailedTitle - let errorMessage: String - - let nsError = error as NSError - - if let message = nsError.userInfo[NSLocalizedDescriptionKey] as? String { - errorMessage = message - } else { - errorMessage = TchapL10n.errorMessageDefault - } - - return ErrorPresentableImpl(title: errorTitle, message: errorMessage) - } } // MARK: - MasterTabBarControllerDelegate diff --git a/Tchap/Managers/Invite/InviteService.swift b/Tchap/Managers/Invite/InviteService.swift deleted file mode 100644 index 3c9950e29e..0000000000 --- a/Tchap/Managers/Invite/InviteService.swift +++ /dev/null @@ -1,202 +0,0 @@ -/* - Copyright 2019 New Vector Ltd - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -//import Foundation -//import MatrixSDK -// -//enum InviteServiceError: Error { -// case unknown -//} -// -///// `InviteService` is used to invite someone to join Tchap -//final class InviteService: InviteServiceType { -// -// // MARK: Private -// private let session: MXSession -// -// private let discussionFinder: DiscussionFinderType -// private let userService: UserServiceType -// private let roomService: RoomServiceType -// -// private var roomInProcess: MXRoom? -// -// // MARK: - Public -// init(session: MXSession) { -// self.session = session -// self.discussionFinder = DiscussionFinder(session: session) -// self.userService = UserService(session: session) -// self.roomService = RoomService(session: session) -// } -// -// func sendEmailInvite(to email: String, completion: @escaping (MXResponse) -> Void) { -// // Start the invite process by checking whether a Tchap account has been created for this email. -// self.discoverUser(with: email, completion: { [weak self] (response) in -// switch response { -// case .success(let result): -// switch result { -// case .bound(let userID): -// completion(.success(.inviteIgnoredForDiscoveredUser(userID: userID))) -// case .unbound: -// // Pursue the invite process by checking whether an invite has been already sent -// self?.discussionFinder.getDiscussionIdentifier(for: email) { [weak self] (response) in -// guard let self = self else { -// return -// } -// -// switch response { -// case .success(let result): -// switch result { -// case .joinedDiscussion(let roomID): -// // There is already a discussion with this email -// // We do not re-invite the NoTchapUser except if -// // the email is bound to the external instance (for which the invites may expire). -// self.userService.isEmailBoundToTheExternalHost(email) { [weak self] (response) in -// switch response { -// case .success(let isExternal): -// if isExternal { -// // Revoke the pending invite and leave this empty discussion, we will invite again this email. -// // We don't have a way for the moment to check if the invite expired or not... -// self?.revokePendingInviteAndLeave(roomID) { [weak self] (response) in -// switch response { -// case .success: -// // Send the new invite -// self?.createDiscussion(with: email, completion: completion) -// case .failure: -// // Ignore the error, notify the user that the invite has been already sent -// completion(.success(.inviteAlreadySent(roomID: roomID))) -// } -// } -// } else { -// // Notify the user that the invite has been already sent -// completion(.success(.inviteAlreadySent(roomID: roomID))) -// } -// case .failure: -// // Ignore the error, notify the user that the invite has been already sent -// completion(.success(.inviteAlreadySent(roomID: roomID))) -// } -// } -// case .noDiscussion: -// // Send the invite if the email is authorized -// self.createDiscussion(with: email, completion: completion) -// default: -// break -// } -// case .failure(let error): -// MXLog.debug("[InviteService] sendEmailInvite failed") -// completion(MXResponse.failure(error)) -// } -// } -// } -// case .failure(let error): -// completion(MXResponse.failure(error)) -// } -// }) -// } -// -// // MARK: - Private -// -// // Check whether a Tchap account has been created for this email. The closure returns a nil identifier when no account exists. -// private func discoverUser(with email: String, completion: @escaping (MXResponse) -> Void) { -// guard let identityService = self.session.identityService else { -// MXLog.debug("[InviteService] discoverUser failed") -// completion(MXResponse.failure(InviteServiceError.unknown)) -// return -// } -// let pid = MX3PID(medium: .email, address: email) -// _ = identityService.lookup3PIDs([pid]) { response in -// if let responseValue = response.value?[pid] { -// completion(MXResponse.success(.bound(userID: responseValue))) -// } else { -// completion(MXResponse.success(.unbound)) -// } -// } -// } -// -// private func createDiscussion(with email: String, completion: @escaping (MXResponse) -> Void) { -// self.userService.isEmailAuthorized(email) { [weak self] (response) in -// switch response { -// case .success(let isAuthorized): -// if isAuthorized { -// guard -// let matrixRestClient = self?.session.matrixRestClient, -// let identityServer = matrixRestClient.identityServer ?? matrixRestClient.homeserver, -// let identityServerURL = URL(string: identityServer), -// let identityServerHost = identityServerURL.host else { -// return -// } -// -// let thirdPartyId = MXInvite3PID() -// thirdPartyId.medium = MX3PID.Medium.email.identifier -// thirdPartyId.address = email -// thirdPartyId.identityServer = identityServerHost -// -// _ = self?.roomService.createDiscussionWithThirdPartyID(thirdPartyId, completion: { (response) in -// switch response { -// case .success(let roomID): -// completion(.success(.inviteHasBeenSent(roomID: roomID))) -// case .failure(let error): -// MXLog.debug("[InviteService] createDiscussion failed") -// completion(MXResponse.failure(error)) -// } -// }) -// } else { -// completion(.success(.inviteIgnoredForUnauthorizedEmail)) -// } -// -// case .failure(let error): -// completion(MXResponse.failure(error)) -// } -// } -// } -// -// private func revokePendingInviteAndLeave(_ roomID: String, completion: @escaping (MXResponse) -> Void) { -// guard let room = self.session.room(withRoomId: roomID) else { -// MXLog.debug("[InviteService] unable to revoke invite") -// completion(.failure(InviteServiceError.unknown)) -// return -// } -// -// roomInProcess = room -// room.state { [weak self] roomState in -// guard let self = self else { -// return -// } -// -// if let thirdPartyInvite = roomState?.thirdPartyInvites?.first, -// let token = thirdPartyInvite.token { -// self.roomInProcess?.sendStateEvent(.roomThirdPartyInvite, content: [:], stateKey: token) { [weak self] (response) in -// guard let self = self else { -// return -// } -// -// switch response { -// case .success: -// // Leave now the room -// self.session.leaveRoom(roomID, completion: completion) -// case .failure(let error): -// completion(.failure(error)) -// } -// -// self.roomInProcess = nil -// } -// } else { -// MXLog.debug("[InviteService] unable to revoke invite (no pending invite)") -// self.session.leaveRoom(roomID, completion: completion) -// self.roomInProcess = nil -// } -// } -// } -//} diff --git a/Tchap/Managers/Invite/InviteServiceType.swift b/Tchap/Managers/Invite/InviteServiceType.swift deleted file mode 100644 index 9e36b5f943..0000000000 --- a/Tchap/Managers/Invite/InviteServiceType.swift +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright 2019 New Vector Ltd - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -import Foundation - -///// List the different result cases -//enum { -// case inviteHasBeenSent(roomID: String) -// case inviteAlreadySent(roomID: String) -// case inviteIgnoredForDiscoveredUser(userID: String) -// case inviteIgnoredForUnauthorizedEmail -//} -// -// -///// List the different discover user result cases -//enum InviteServiceDiscoverUserResult { -// case bound(userID: String) -// case unbound -//} -// -///// Protocol describing a service used to invite someone to join Tchap. -//protocol InviteServiceType { -// -// /// Invite a contact by inviting him in a direct chat (if this is not already done). -// /// -// /// - Parameters: -// /// - email: an email address. -// /// - completion: A closure called when the operation complete. See InviteServiceResult values. -// func sendEmailInvite(to email: String, completion: @escaping (MXResponse) -> Void) -//} From 52e76b04fe4ee6edc82db7d2fb49422738b7308d Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Thu, 12 Oct 2023 17:23:14 +0200 Subject: [PATCH 4/4] Clean code : remove Tchap specific code or comment unused code --- Riot/Modules/Application/AppCoordinator.swift | 3 --- .../Home/AllChats/AllChatsCoordinator.swift | 14 +++++++++----- .../Modules/SideMenu/SideMenuCoordinator.swift | 2 ++ .../SplitView/SplitViewCoordinator.swift | 4 ---- .../SplitView/SplitViewCoordinatorType.swift | 4 ---- .../SplitViewMasterCoordinatorProtocol.swift | 4 ---- Riot/Modules/TabBar/TabBarCoordinator.swift | 18 +++++++----------- 7 files changed, 18 insertions(+), 31 deletions(-) diff --git a/Riot/Modules/Application/AppCoordinator.swift b/Riot/Modules/Application/AppCoordinator.swift index faf6867384..39719a8961 100755 --- a/Riot/Modules/Application/AppCoordinator.swift +++ b/Riot/Modules/Application/AppCoordinator.swift @@ -573,9 +573,6 @@ extension AppCoordinator: SplitViewCoordinatorDelegate { // MARK: - SideMenuCoordinatorDelegate extension AppCoordinator: SideMenuCoordinatorDelegate { func sideMenuCoordinator(_ coordinator: SideMenuCoordinatorType, didTapMenuItem menuItem: SideMenuItem, fromSourceView sourceView: UIView) { - if menuItem == .inviteFriends { - self.splitViewCoordinator?.presentInvitePeople() - } } } diff --git a/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift b/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift index 873a6ad985..73fecc7901 100644 --- a/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift +++ b/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift @@ -30,11 +30,6 @@ class AllChatsCoordinatorParameters { } class AllChatsCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { - func presentInvitePeople() { - // - } - - // MARK: Properties // MARK: Private @@ -641,6 +636,15 @@ class AllChatsCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { // return versionCheckCoordinator // } + private func showInviteFriends(from sourceView: UIView?) { + // Tchap: commented because Tchap now uses Element Direct Message mechanism + + // let myUserId = self.parameters.userSessionsService.mainUserSession?.userId ?? "" + // + // let inviteFriendsPresenter = InviteFriendsPresenter() + // inviteFriendsPresenter.present(for: myUserId, from: self.navigationRouter.toPresentable(), sourceView: sourceView, animated: true) + } + private func showBugReport() { let bugReportViewController = BugReportViewController() diff --git a/Riot/Modules/SideMenu/SideMenuCoordinator.swift b/Riot/Modules/SideMenu/SideMenuCoordinator.swift index 047bd0a6ac..7e7d036435 100644 --- a/Riot/Modules/SideMenu/SideMenuCoordinator.swift +++ b/Riot/Modules/SideMenu/SideMenuCoordinator.swift @@ -239,6 +239,8 @@ final class SideMenuCoordinator: NSObject, SideMenuCoordinatorType { } private func showInviteFriends(from sourceView: UIView?) { +// Tchap: commented because Tchap now uses Element Direct Message mechanism + // let myUserId = self.parameters.userSessionsService.mainUserSession?.userId ?? "" // // let inviteFriendsPresenter = InviteFriendsPresenter() diff --git a/Riot/Modules/SplitView/SplitViewCoordinator.swift b/Riot/Modules/SplitView/SplitViewCoordinator.swift index 79631fccda..141be19af9 100644 --- a/Riot/Modules/SplitView/SplitViewCoordinator.swift +++ b/Riot/Modules/SplitView/SplitViewCoordinator.swift @@ -166,10 +166,6 @@ final class SplitViewCoordinator: NSObject, SplitViewCoordinatorType { func showAppStateIndicator(with text: String, icon: UIImage?) { masterCoordinator?.showAppStateIndicator(with: text, icon: icon) } - - func presentInvitePeople() { - masterCoordinator?.presentInvitePeople() - } // MARK: - Private methods diff --git a/Riot/Modules/SplitView/SplitViewCoordinatorType.swift b/Riot/Modules/SplitView/SplitViewCoordinatorType.swift index 080869e5f3..cfd04ed3e8 100644 --- a/Riot/Modules/SplitView/SplitViewCoordinatorType.swift +++ b/Riot/Modules/SplitView/SplitViewCoordinatorType.swift @@ -45,8 +45,4 @@ protocol SplitViewCoordinatorType: Coordinator, Presentable { /// Hide the message related to the application state currently displayed. func hideAppStateIndicator() - - // Tchap: redirect to invite people alert - /// Present invite people alert (with textField) - func presentInvitePeople() } diff --git a/Riot/Modules/TabBar/SplitViewMasterCoordinatorProtocol.swift b/Riot/Modules/TabBar/SplitViewMasterCoordinatorProtocol.swift index 1cb7825b61..d83d6fc06a 100644 --- a/Riot/Modules/TabBar/SplitViewMasterCoordinatorProtocol.swift +++ b/Riot/Modules/TabBar/SplitViewMasterCoordinatorProtocol.swift @@ -46,8 +46,4 @@ protocol SplitViewMasterCoordinatorProtocol: Coordinator, SplitViewMasterPresent /// Hide the message related to the application state currently displayed. func hideAppStateIndicator() - - // Tchap: redirect to invite people alert - /// Present invite people alert (with textField) - func presentInvitePeople() } diff --git a/Riot/Modules/TabBar/TabBarCoordinator.swift b/Riot/Modules/TabBar/TabBarCoordinator.swift index 198ca5e6ae..e318fe3188 100644 --- a/Riot/Modules/TabBar/TabBarCoordinator.swift +++ b/Riot/Modules/TabBar/TabBarCoordinator.swift @@ -236,12 +236,6 @@ final class TabBarCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { appSateIndicator = nil } - func presentInvitePeople() { - promptUserToFillAnEmailToInvite { [weak self] email in - - } - } - // MARK: - SplitViewMasterPresentable var selectedNavigationRouter: NavigationRouterType? { @@ -260,10 +254,12 @@ final class TabBarCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { } private func showInviteFriends(from sourceView: UIView?) { - let myUserId = self.parameters.userSessionsService.mainUserSession?.userId ?? "" - - let inviteFriendsPresenter = InviteFriendsPresenter() - inviteFriendsPresenter.present(for: myUserId, from: self.navigationRouter.toPresentable(), sourceView: sourceView, animated: true) +// Tchap: commented because Tchap now uses Element Direct Message mechanism + +// let myUserId = self.parameters.userSessionsService.mainUserSession?.userId ?? "" +// +// let inviteFriendsPresenter = InviteFriendsPresenter() +// inviteFriendsPresenter.present(for: myUserId, from: self.navigationRouter.toPresentable(), sourceView: sourceView, animated: true) } private func showBugReport() { @@ -795,7 +791,7 @@ final class TabBarCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { var subMenuActions: [UIAction] = [] if BuildSettings.sideMenuShowInviteFriends { subMenuActions.append(UIAction(title: VectorL10n.inviteTo(AppInfo.current.displayName), image: UIImage(systemName: "envelope")) { [weak self] action in - self?.showInviteFriends(from: nil) + self?.showInviteFriends(from: nil) }) }