mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Handle external links to a user. (#2690)
This commit is contained in:
@@ -129,7 +129,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
} else {
|
||||
stateMachine.tryEvent(.presentRoomMemberDetails(userID: userID), userInfo: EventUserInfo(animated: animated))
|
||||
}
|
||||
case .genericCallLink, .oidcCallback, .settings, .chatBackupSettings:
|
||||
case .userProfile, .genericCallLink, .oidcCallback, .settings, .chatBackupSettings:
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -875,7 +875,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
roomProxy: roomProxy,
|
||||
clientProxy: userSession.clientProxy,
|
||||
mediaProvider: userSession.mediaProvider,
|
||||
userIndicatorController: userIndicatorController)
|
||||
userIndicatorController: userIndicatorController,
|
||||
analytics: analytics)
|
||||
let coordinator = RoomMemberDetailsScreenCoordinator(parameters: params)
|
||||
|
||||
coordinator.actions.sink { [weak self] action in
|
||||
@@ -883,8 +884,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
switch action {
|
||||
case .openUserProfile:
|
||||
stateMachine.tryEvent(.presentUserProfile(userID: userID))
|
||||
case .openDirectChat(let displayName):
|
||||
openDirectChat(with: userID, displayName: displayName)
|
||||
case .openDirectChat(let roomID):
|
||||
stateMachine.tryEvent(.presentChildRoom(roomID: roomID))
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
@@ -896,16 +897,20 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
private func replaceRoomMemberDetailsWithUserProfile(userID: String) {
|
||||
let parameters = UserProfileScreenCoordinatorParameters(userID: userID,
|
||||
isPresentedModally: false,
|
||||
clientProxy: userSession.clientProxy,
|
||||
mediaProvider: userSession.mediaProvider,
|
||||
userIndicatorController: userIndicatorController)
|
||||
userIndicatorController: userIndicatorController,
|
||||
analytics: analytics)
|
||||
let coordinator = UserProfileScreenCoordinator(parameters: parameters)
|
||||
coordinator.actionsPublisher.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .openDirectChat(let displayName):
|
||||
openDirectChat(with: userID, displayName: displayName)
|
||||
case .openDirectChat(let roomID):
|
||||
stateMachine.tryEvent(.presentChildRoom(roomID: roomID))
|
||||
case .dismiss:
|
||||
break // Not supported when pushed.
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
@@ -917,37 +922,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
private func openDirectChat(with userID: String, displayName: String?) {
|
||||
let loadingIndicatorIdentifier = "OpenDirectChatLoadingIndicator"
|
||||
|
||||
userIndicatorController.submitIndicator(UserIndicator(id: loadingIndicatorIdentifier,
|
||||
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true, allowsInteraction: false),
|
||||
title: L10n.commonLoading,
|
||||
persistent: true))
|
||||
|
||||
Task { [weak self] in
|
||||
guard let self else { return }
|
||||
|
||||
let currentDirectRoom = await userSession.clientProxy.directRoomForUserID(userID)
|
||||
switch currentDirectRoom {
|
||||
case .success(.some(let roomID)):
|
||||
stateMachine.tryEvent(.presentChildRoom(roomID: roomID))
|
||||
case .success(nil):
|
||||
switch await userSession.clientProxy.createDirectRoom(with: userID, expectedRoomName: displayName) {
|
||||
case .success(let roomID):
|
||||
analytics.trackCreatedRoom(isDM: true)
|
||||
stateMachine.tryEvent(.presentChildRoom(roomID: roomID))
|
||||
case .failure:
|
||||
userIndicatorController.alertInfo = .init(id: UUID())
|
||||
}
|
||||
case .failure:
|
||||
userIndicatorController.alertInfo = .init(id: UUID())
|
||||
}
|
||||
|
||||
userIndicatorController.retractIndicatorWithId(loadingIndicatorIdentifier)
|
||||
}
|
||||
}
|
||||
|
||||
private func presentMessageForwarding(for itemID: TimelineItemIdentifier) {
|
||||
guard let roomSummaryProvider = userSession.clientProxy.alternateRoomSummaryProvider, let eventID = itemID.eventID else {
|
||||
fatalError()
|
||||
|
||||
@@ -195,6 +195,8 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
case .roomList, .roomMemberDetails:
|
||||
self.roomFlowCoordinator?.handleAppRoute(appRoute, animated: animated)
|
||||
case .userProfile(let userID):
|
||||
stateMachine.processEvent(.showUserProfileScreen(userID: userID), userInfo: .init(animated: animated))
|
||||
case .genericCallLink(let url):
|
||||
self.navigationSplitCoordinator.setSheetCoordinator(GenericCallLinkCoordinator(parameters: .init(url: url)), animated: animated)
|
||||
case .oidcCallback:
|
||||
@@ -302,6 +304,11 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
presentRoomDirectorySearch()
|
||||
case (.roomDirectorySearchScreen, .dismissedRoomDirectorySearchScreen, .roomList):
|
||||
dismissRoomDirectorySearch()
|
||||
|
||||
case (_, .showUserProfileScreen(let userID), .userProfileScreen):
|
||||
presentUserProfileScreen(userID: userID, animated: animated)
|
||||
case (.userProfileScreen, .dismissedUserProfileScreen, .roomList):
|
||||
break
|
||||
|
||||
default:
|
||||
fatalError("Unknown transition: \(context)")
|
||||
@@ -654,4 +661,36 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
private func dismissRoomDirectorySearch() {
|
||||
navigationSplitCoordinator.setFullScreenCoverCoordinator(nil)
|
||||
}
|
||||
|
||||
// MARK: User Profile
|
||||
|
||||
private func presentUserProfileScreen(userID: String, animated: Bool) {
|
||||
clearRoute(animated: animated)
|
||||
|
||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||
let parameters = UserProfileScreenCoordinatorParameters(userID: userID,
|
||||
isPresentedModally: true,
|
||||
clientProxy: userSession.clientProxy,
|
||||
mediaProvider: userSession.mediaProvider,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
analytics: analytics)
|
||||
let coordinator = UserProfileScreenCoordinator(parameters: parameters)
|
||||
coordinator.actionsPublisher.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .openDirectChat(let roomID):
|
||||
navigationSplitCoordinator.setSheetCoordinator(nil)
|
||||
stateMachine.processEvent(.selectRoom(roomID: roomID, showingRoomDetails: false))
|
||||
case .dismiss:
|
||||
navigationSplitCoordinator.setSheetCoordinator(nil)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
navigationStackCoordinator.setRootCoordinator(coordinator, animated: false)
|
||||
navigationSplitCoordinator.setSheetCoordinator(navigationStackCoordinator, animated: animated) { [weak self] in
|
||||
self?.stateMachine.processEvent(.dismissedUserProfileScreen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class UserSessionFlowCoordinatorStateMachine {
|
||||
/// Showing the home screen. The `selectedRoomID` represents the timeline shown on the detail panel (if any)
|
||||
case roomList(selectedRoomID: String?)
|
||||
|
||||
/// Showing the session verification flows
|
||||
/// Showing the feedback screen.
|
||||
case feedbackScreen(selectedRoomID: String?)
|
||||
|
||||
/// Showing the settings screen
|
||||
@@ -45,10 +45,13 @@ class UserSessionFlowCoordinatorStateMachine {
|
||||
/// Showing Room Directory Search screen
|
||||
case roomDirectorySearchScreen(selectedRoomID: String?)
|
||||
|
||||
/// Showing the user profile screen. This screen clears the navigation.
|
||||
case userProfileScreen
|
||||
|
||||
/// The selected room ID from the state if available.
|
||||
var selectedRoomID: String? {
|
||||
switch self {
|
||||
case .initial:
|
||||
case .initial, .userProfileScreen:
|
||||
nil
|
||||
case .roomList(let selectedRoomID),
|
||||
.feedbackScreen(let selectedRoomID),
|
||||
@@ -102,9 +105,15 @@ class UserSessionFlowCoordinatorStateMachine {
|
||||
/// Logout has been cancelled
|
||||
case dismissedLogoutConfirmationScreen
|
||||
|
||||
/// Request presentation of the room directory search screen.
|
||||
case showRoomDirectorySearchScreen
|
||||
|
||||
/// The room directory search screen has been dismissed.
|
||||
case dismissedRoomDirectorySearchScreen
|
||||
|
||||
/// Request presentation of the user profile screen.
|
||||
case showUserProfileScreen(userID: String)
|
||||
/// The user profile screen has been dismissed.
|
||||
case dismissedUserProfileScreen
|
||||
}
|
||||
|
||||
private let stateMachine: StateMachine<State, Event>
|
||||
@@ -169,6 +178,11 @@ class UserSessionFlowCoordinatorStateMachine {
|
||||
return .roomDirectorySearchScreen(selectedRoomID: selectedRoomID)
|
||||
case (.roomDirectorySearchScreen(let selectedRoomID), .dismissedRoomDirectorySearchScreen):
|
||||
return .roomList(selectedRoomID: selectedRoomID)
|
||||
|
||||
case (_, .showUserProfileScreen):
|
||||
return .userProfileScreen
|
||||
case (.userProfileScreen, .dismissedUserProfileScreen):
|
||||
return .roomList(selectedRoomID: nil)
|
||||
|
||||
default:
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user