From aedc1cbf1f3791832bebe39cb57d2cc44b793161 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Mon, 27 Oct 2025 19:02:39 +0100 Subject: [PATCH] refactored room flow coordinator to use the members flow coordinator --- .../RoomFlowCoordinator.swift | 148 ++++++------------ .../RoomFlowCoordinatorStateMachine.swift | 37 ++--- .../RoomMembersFlowCoordinator.swift | 77 ++++++--- .../SpaceFlowCoordinator.swift | 1 + 4 files changed, 109 insertions(+), 154 deletions(-) diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift index 6146a7044..f05aac533 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift @@ -85,6 +85,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { private var childRoomFlowCoordinator: RoomFlowCoordinator? // periphery:ignore - retaining purpose private var spaceFlowCoordinator: SpaceFlowCoordinator? + // periphery:ignore - retaining purpose + private var membersFlowCoordinator: RoomMembersFlowCoordinator? private let stateMachine: StateMachine = .init(state: .initial) @@ -129,7 +131,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { await handleRoomRoute(roomID: roomID, via: via, animated: animated) } case .childRoom(let roomID, let via): - if case .presentingChild = stateMachine.state, let childRoomFlowCoordinator { + if case .membersFlow = stateMachine.state, let membersFlowCoordinator { + membersFlowCoordinator.handleAppRoute(appRoute, animated: animated) + } else if case .presentingChild = stateMachine.state, let childRoomFlowCoordinator { childRoomFlowCoordinator.handleAppRoute(appRoute, animated: animated) } else if roomID != roomProxy.id { stateMachine.tryEvent(.startChildFlow(roomID: roomID, via: via, entryPoint: .room), userInfo: EventUserInfo(animated: animated)) @@ -152,10 +156,12 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { } case .roomMemberDetails(let userID): // Always assume this will be presented on the child, external permalinks to a user aren't for a room member. - if case .presentingChild = stateMachine.state, let childRoomFlowCoordinator { + if case .membersFlow = stateMachine.state, let membersFlowCoordinator { + membersFlowCoordinator.handleAppRoute(.roomMemberDetails(userID: userID), animated: animated) + } else if case .presentingChild = stateMachine.state, let childRoomFlowCoordinator { childRoomFlowCoordinator.handleAppRoute(appRoute, animated: animated) } else { - stateMachine.tryEvent(.presentRoomMemberDetails(userID: userID), userInfo: EventUserInfo(animated: animated)) + stateMachine.tryEvent(.startMembersFlow(entryPoint: .roomMember(userID: userID)), userInfo: EventUserInfo(animated: animated)) } case .thread(let roomID, let threadRootEventID, let focusEventID): Task { @@ -207,7 +213,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { } private func handleChildEventRoute(eventID: String, roomID: String, via: [String], animated: Bool) { - if case .presentingChild = stateMachine.state, let childRoomFlowCoordinator { + if case .membersFlow = stateMachine.state, let membersFlowCoordinator { + membersFlowCoordinator.handleAppRoute(.childEvent(eventID: eventID, roomID: roomID, via: via), animated: animated) + } else if case .presentingChild = stateMachine.state, let childRoomFlowCoordinator { childRoomFlowCoordinator.handleAppRoute(.childEvent(eventID: eventID, roomID: roomID, via: via), animated: animated) } else if roomID != roomProxy.id { stateMachine.tryEvent(.startChildFlow(roomID: roomID, via: via, entryPoint: .eventID(eventID)), userInfo: EventUserInfo(animated: animated)) @@ -439,9 +447,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { case (.roomDetails, .presentNotificationSettingsScreen, .notificationSettings): presentNotificationSettingsScreen() - case (.roomDetails, .presentRoomMembersList, .roomMembersList): - presentRoomMembersList() - case (.roomDetails, .presentPollsHistory, .pollsHistory): Task { await self.presentRoomPollsHistory(animated: animated) } @@ -478,23 +483,22 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { presentDeclineAndBlockScreen(userID: userID) // Other + + case (_, .startMembersFlow(let entryPoint), .membersFlow): + startMembersFlow(entryPoint: entryPoint, animated: animated) + case (.membersFlow, .stopMembersFlow, _): + membersFlowCoordinator = nil case (_, .startChildFlow(let roomID, let via, let entryPoint), .presentingChild): startChildFlow(for: roomID, via: via, entryPoint: entryPoint) case (.presentingChild, .dismissChildFlow, _): childRoomFlowCoordinator = nil - case (_, .presentRoomMemberDetails, .roomMemberDetails(let userID, _)): - presentRoomMemberDetails(userID: userID) - case (_, .presentKnockRequestsListScreen, .knockRequestsList): presentKnockRequestsList() case (.notificationSettings, .presentGlobalNotificationSettingsScreen, .globalNotificationSettings): presentGlobalNotificationSettingsScreen() - - case (.roomMemberDetails, .presentUserProfile(let userID), .userProfile): - replaceRoomMemberDetailsWithUserProfile(userID: userID) case (.pollsHistory, .presentPollForm(let mode), .pollsHistoryForm): guard let timelineController = (context.userInfo as? EventUserInfo)?.timelineController else { @@ -677,7 +681,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { stateMachine.tryEvent(.presentMapNavigator(interactionMode: .viewOnly(geoURI: geoURI, description: description)), userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) case .presentRoomMemberDetails(userID: let userID): - stateMachine.tryEvent(.presentRoomMemberDetails(userID: userID)) + stateMachine.tryEvent(.startMembersFlow(entryPoint: .roomMember(userID: userID))) case .presentMessageForwarding(let forwardingItem): stateMachine.tryEvent(.presentMessageForwarding(forwardingItem: forwardingItem)) case .presentCallScreen: @@ -769,7 +773,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { stateMachine.tryEvent(.presentEmojiPicker(itemID: itemID, selectedEmojis: selectedEmojis), userInfo: EventUserInfo(animated: animated, timelineController: timelineController)) case .presentRoomMemberDetails(let userID): - stateMachine.tryEvent(.presentRoomMemberDetails(userID: userID)) + stateMachine.tryEvent(.startMembersFlow(entryPoint: .roomMember(userID: userID))) case .presentMessageForwarding(let forwardingItem): stateMachine.tryEvent(.presentMessageForwarding(forwardingItem: forwardingItem)) case .presentResolveSendFailure(let failure, let sendHandle): @@ -888,7 +892,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { case .leftRoom: stateMachine.tryEvent(.dismissFlow) case .presentRoomMembersList: - stateMachine.tryEvent(.presentRoomMembersList) + stateMachine.tryEvent(.startMembersFlow(entryPoint: .roomMembersList)) case .presentRoomDetailsEditScreen: stateMachine.tryEvent(.presentRoomDetailsEditScreen) case .presentNotificationSettingsScreen: @@ -910,7 +914,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { case .presentSecurityAndPrivacyScreen: stateMachine.tryEvent(.presentSecurityAndPrivacyScreen) case .presentRecipientDetails(let userID): - stateMachine.tryEvent(.presentRoomMemberDetails(userID: userID)) + stateMachine.tryEvent(.startMembersFlow(entryPoint: .roomMember(userID: userID))) case .presentReportRoomScreen: stateMachine.tryEvent(.presentReportRoomScreen) case .transferOwnership: @@ -936,31 +940,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { } } - private func presentRoomMembersList() { - let parameters = RoomMembersListScreenCoordinatorParameters(userSession: userSession, - roomProxy: roomProxy, - userIndicatorController: flowParameters.userIndicatorController, - analytics: flowParameters.analytics) - let coordinator = RoomMembersListScreenCoordinator(parameters: parameters) - - coordinator.actions - .sink { [weak self] action in - guard let self else { return } - - switch action { - case .invite: - stateMachine.tryEvent(.presentInviteUsersScreen) - case .selectedMember(let member): - stateMachine.tryEvent(.presentRoomMemberDetails(userID: member.userID)) - } - } - .store(in: &cancellables) - - navigationStackCoordinator.push(coordinator) { [weak self] in - self?.stateMachine.tryEvent(.dismissRoomMembersList) - } - } - private func presentKnockRequestsList() { let parameters = KnockRequestsListScreenCoordinatorParameters(roomProxy: roomProxy, mediaProvider: userSession.mediaProvider, @@ -1214,65 +1193,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { } } - private func presentRoomMemberDetails(userID: String) { - let params = RoomMemberDetailsScreenCoordinatorParameters(userID: userID, - roomProxy: roomProxy, - userSession: userSession, - userIndicatorController: flowParameters.userIndicatorController, - analytics: flowParameters.analytics) - let coordinator = RoomMemberDetailsScreenCoordinator(parameters: params) - - coordinator.actions.sink { [weak self] action in - guard let self else { return } - switch action { - case .openUserProfile: - stateMachine.tryEvent(.presentUserProfile(userID: userID)) - case .openDirectChat(let roomID): - stateMachine.tryEvent(.startChildFlow(roomID: roomID, via: [], entryPoint: .room)) - case .startCall(let roomProxy): - actionsSubject.send(.presentCallScreen(roomProxy: roomProxy)) - case .verifyUser(let userID): - actionsSubject.send(.verifyUser(userID: userID)) - } - } - .store(in: &cancellables) - - navigationStackCoordinator.push(coordinator) { [weak self] in - self?.stateMachine.tryEvent(.dismissRoomMemberDetails) - } - } - - private func replaceRoomMemberDetailsWithUserProfile(userID: String) { - let parameters = UserProfileScreenCoordinatorParameters(userID: userID, - isPresentedModally: false, - userSession: userSession, - userIndicatorController: flowParameters.userIndicatorController, - analytics: flowParameters.analytics) - let coordinator = UserProfileScreenCoordinator(parameters: parameters) - coordinator.actionsPublisher.sink { [weak self] action in - guard let self else { return } - - switch action { - case .openDirectChat(let roomID): - stateMachine.tryEvent(.startChildFlow(roomID: roomID, via: [], entryPoint: .room)) - case .startCall(let roomProxy): - actionsSubject.send(.presentCallScreen(roomProxy: roomProxy)) - case .dismiss: - break // Not supported when pushed. - } - } - .store(in: &cancellables) - - // Replace the RoomMemberDetailsScreen without any animation. - // If this pop and push happens before the previous navigation is completed it might break screen presentation logic - DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) { - self.navigationStackCoordinator.pop(animated: false) - self.navigationStackCoordinator.push(coordinator, animated: false) { [weak self] in - self?.stateMachine.tryEvent(.dismissUserProfile) - } - } - } - private func presentMessageForwarding(with forwardingItem: MessageForwardingItem) { let roomSummaryProvider = userSession.clientProxy.alternateRoomSummaryProvider @@ -1558,7 +1478,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { navigationStackCoordinator.setSheetCoordinator(nil) case .displayUser(let userID): navigationStackCoordinator.setSheetCoordinator(nil) - stateMachine.tryEvent(.presentRoomMemberDetails(userID: userID)) + stateMachine.tryEvent(.startMembersFlow(entryPoint: .roomMember(userID: userID))) case .forwardedMessageToRoom(let roomID): navigationStackCoordinator.setSheetCoordinator(nil) stateMachine.tryEvent(.startChildFlow(roomID: roomID, via: [], entryPoint: .room)) @@ -1633,6 +1553,30 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { coordinator.start() } + private func startMembersFlow(entryPoint: RoomMembersFlowCoordinatorEntryPoint, animated: Bool) { + let flowCoordinator = RoomMembersFlowCoordinator(entryPoint: entryPoint, + animatedEntry: animated, + roomProxy: roomProxy, + navigationStackCoordinator: navigationStackCoordinator, + flowParameters: flowParameters) + + flowCoordinator.actions.sink { [weak self] action in + guard let self else { return } + switch action { + case .finished: + stateMachine.tryEvent(.stopMembersFlow) + case .presentCallScreen(let roomProxy): + actionsSubject.send(.presentCallScreen(roomProxy: roomProxy)) + case .verifyUser(let userID): + actionsSubject.send(.verifyUser(userID: userID)) + } + } + .store(in: &cancellables) + + flowCoordinator.start() + membersFlowCoordinator = flowCoordinator + } + private static let loadingIndicatorID = "\(RoomFlowCoordinator.self)-Loading" private func showLoadingIndicator(delay: Duration? = nil, diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinatorStateMachine.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinatorStateMachine.swift index 97f813c1c..0a1415740 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinatorStateMachine.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinatorStateMachine.swift @@ -64,9 +64,6 @@ extension RoomFlowCoordinator { case roomDetailsEditScreen case notificationSettings case globalNotificationSettings - case roomMembersList - case roomMemberDetails(userID: String, previousState: State) - case userProfile(userID: String, previousState: State) case inviteUsersScreen(previousState: State) case mediaUploadPicker(mode: MediaPickerScreenMode, previousState: State) case mediaUploadPreview(mediaURLs: [URL], previousState: State) @@ -93,6 +90,8 @@ extension RoomFlowCoordinator { /// A space flow is in progress case spaceFlow(previousState: State) + /// A members flow is in progress + case membersFlow(previousState: State) } struct EventUserInfo { @@ -130,15 +129,6 @@ extension RoomFlowCoordinator { case presentGlobalNotificationSettingsScreen case dismissGlobalNotificationSettingsScreen - case presentRoomMembersList - case dismissRoomMembersList - - case presentRoomMemberDetails(userID: String) - case dismissRoomMemberDetails - - case presentUserProfile(userID: String) - case dismissUserProfile - case presentInviteUsersScreen case dismissInviteUsersScreen @@ -189,6 +179,9 @@ extension RoomFlowCoordinator { case presentDeclineAndBlockScreen(userID: String) case dismissDeclineAndBlockScreen + + case startMembersFlow(entryPoint: RoomMembersFlowCoordinatorEntryPoint) + case stopMembersFlow } // swiftlint:disable:next function_body_length @@ -303,11 +296,6 @@ extension RoomFlowCoordinator { case (.roomDetailsEditScreen, .dismissRoomDetailsEditScreen): return .roomDetails(isRoot: false) - case (.roomDetails, .presentRoomMembersList): - return .roomMembersList - case (.roomMembersList, .dismissRoomMembersList): - return .roomDetails(isRoot: false) - case (.roomDetails, .presentNotificationSettingsScreen): return .notificationSettings case (.notificationSettings, .dismissNotificationSettingsScreen): @@ -353,6 +341,11 @@ extension RoomFlowCoordinator { return .joinRoomScreen // Other + + case (_, .startMembersFlow): + return .membersFlow(previousState: fromState) + case (.membersFlow(let previousState), .stopMembersFlow): + return previousState case (_, .startChildFlow(let roomID, _, _)): return .presentingChild(childRoomID: roomID, previousState: fromState) @@ -363,11 +356,6 @@ extension RoomFlowCoordinator { return .spaceFlow(previousState: previousState) case (.spaceFlow(let previousState), .finishedSpaceFlow): return previousState - - case (_, .presentRoomMemberDetails(userID: let userID)): - return .roomMemberDetails(userID: userID, previousState: fromState) - case (.roomMemberDetails(_, let previousState), .dismissRoomMemberDetails): - return previousState case (_, .presentKnockRequestsListScreen): return .knockRequestsList(previousState: fromState) @@ -381,11 +369,6 @@ extension RoomFlowCoordinator { return .globalNotificationSettings case (.globalNotificationSettings, .dismissGlobalNotificationSettingsScreen): return .notificationSettings - - case (.roomMemberDetails(_, let previousState), .presentUserProfile(let userID)): - return .userProfile(userID: userID, previousState: previousState) - case (.userProfile(_, let previousState), .dismissUserProfile): - return previousState case (.pollsHistory, .presentPollForm): return .pollsHistoryForm diff --git a/ElementX/Sources/FlowCoordinators/RoomMembersFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/RoomMembersFlowCoordinator.swift index ef7757167..2985bd56f 100644 --- a/ElementX/Sources/FlowCoordinators/RoomMembersFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/RoomMembersFlowCoordinator.swift @@ -15,7 +15,7 @@ enum RoomMembersFlowCoordinatorAction { case verifyUser(userID: String) } -enum RoomMembersFlowCoordinatorEntryPoint: Equatable { +enum RoomMembersFlowCoordinatorEntryPoint: Hashable { /// To be used in a room when a member name is tapped case roomMember(userID: String) /// To be used in the context of room details, space details etc. @@ -52,11 +52,12 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { case presentUserProfile(userID: String) case dismissedUserProfile - case startRoomFlow(roomID: String) + case startRoomFlow(roomID: String, via: [String], eventID: String?) case stopRoomFlow } private let entryPoint: RoomMembersFlowCoordinatorEntryPoint + private let animatedEntry: Bool private let roomProxy: JoinedRoomProxyProtocol private let navigationStackCoordinator: NavigationStackCoordinator private let flowParameters: CommonFlowParameters @@ -72,6 +73,7 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { private var roomFlowCoordinator: RoomFlowCoordinator? init(entryPoint: RoomMembersFlowCoordinatorEntryPoint, + animatedEntry: Bool, roomProxy: JoinedRoomProxyProtocol, navigationStackCoordinator: NavigationStackCoordinator, flowParameters: CommonFlowParameters) { @@ -79,6 +81,7 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { self.roomProxy = roomProxy self.flowParameters = flowParameters self.navigationStackCoordinator = navigationStackCoordinator + self.animatedEntry = animatedEntry stateMachine = .init(state: .initial) configureStateMachine() @@ -87,14 +90,37 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { func start() { switch entryPoint { case .roomMember(let userID): - stateMachine.tryEvent(.presentRoomMemberDetails(userID: userID)) + stateMachine.tryEvent(.presentRoomMemberDetails(userID: userID), userInfo: animatedEntry) case .roomMembersList: - stateMachine.tryEvent(.presentRoomMembersList) + stateMachine.tryEvent(.presentRoomMembersList, userInfo: animatedEntry) } } func handleAppRoute(_ appRoute: AppRoute, animated: Bool) { - fatalError("Unavailable") + switch appRoute { + case .roomMemberDetails(let userID): + if case .roomFlow = stateMachine.state, let roomFlowCoordinator { + roomFlowCoordinator.handleAppRoute(appRoute, animated: animated) + } else { + stateMachine.tryEvent(.presentRoomMemberDetails(userID: userID), userInfo: animated) + } + case .childRoom(let roomID, let via): + if case .roomFlow = stateMachine.state, let roomFlowCoordinator { + roomFlowCoordinator.handleAppRoute(appRoute, animated: animated) + } else { + stateMachine.tryEvent(.startRoomFlow(roomID: roomID, via: via, eventID: nil), userInfo: animated) + } + case .childEvent(let eventID, let roomID, let via): + if case .roomFlow = stateMachine.state, let roomFlowCoordinator { + roomFlowCoordinator.handleAppRoute(appRoute, animated: animated) + } else { + stateMachine.tryEvent(.startRoomFlow(roomID: roomID, via: via, eventID: eventID), userInfo: animated) + } + case .accountProvisioningLink, .roomList, .room, .roomAlias, .childRoomAlias, .roomDetails, .event, + .eventOnRoomAlias, .childEventOnRoomAlias, .userProfile, .call, .genericCallLink, .settings, + .chatBackupSettings, .share, .transferOwnership, .thread: + break + } } func clearRoute(animated: Bool) { @@ -113,14 +139,11 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { switch (fromState, event) { case (.initial, .presentRoomMembersList): return .roomMembersList - case (.initial, .presentRoomMemberDetails(let userID)): - // previous state doesn't matter in this csase - return .roomMemberDetails(userID: userID, previousState: fromState) - case (.roomMembersList, .presentRoomMemberDetails(let userID)): + case (_, .presentRoomMemberDetails(let userID)): return .roomMemberDetails(userID: userID, previousState: fromState) - case (.roomMemberDetails, .dismissedRoomMemberDetails): - return .roomMembersList + case (.roomMemberDetails(_, let previousState), .dismissedRoomMemberDetails): + return previousState case (.roomMembersList, .presentInviteUsersScreen): return .inviteUsersScreen @@ -132,7 +155,7 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { case (.userProfile(_, let previousState), .dismissedUserProfile): return previousState - case (_, .startRoomFlow(let roomID)): + case (_, .startRoomFlow(let roomID, _, _)): return .roomFlow(roomID: roomID, previousState: fromState) case (.roomFlow(_, let previousState), .stopRoomFlow): return previousState @@ -144,14 +167,13 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { stateMachine.addAnyHandler(.any => .any) { [weak self] context in guard let self else { return } + let animated = context.userInfo as? Bool ?? true switch (context.fromState, context.event, context.toState) { case (.initial, .presentRoomMembersList, .roomMembersList): presentRoomMembersList() - case (.initial, .presentRoomMemberDetails, .roomMemberDetails(let userID, _)): - presentRoomMemberDetails(userID: userID) - case (.roomMembersList, .presentRoomMemberDetails, .roomMemberDetails(let userID, _)): - presentRoomMemberDetails(userID: userID) + case (_, .presentRoomMemberDetails, .roomMemberDetails(let userID, _)): + presentRoomMemberDetails(userID: userID, animated: animated) case (.roomMemberDetails, .dismissedRoomMemberDetails, .roomMembersList): break @@ -165,8 +187,8 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { case (.userProfile, .dismissedUserProfile, _): break - case (_, .startRoomFlow(let roomID), .roomFlow): - startRoomFlow(roomID: roomID) + case (_, .startRoomFlow(let roomID, let via, let eventID), .roomFlow): + startRoomFlow(roomID: roomID, via: via, eventID: eventID, animated: animated) case (.roomFlow, .stopRoomFlow, _): roomFlowCoordinator = nil @@ -197,7 +219,7 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { } } - private func presentRoomMemberDetails(userID: String) { + private func presentRoomMemberDetails(userID: String, animated: Bool) { let params = RoomMemberDetailsScreenCoordinatorParameters(userID: userID, roomProxy: roomProxy, userSession: flowParameters.userSession, @@ -211,7 +233,7 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { case .openUserProfile: stateMachine.tryEvent(.presentUserProfile(userID: userID)) case .openDirectChat(let roomID): - stateMachine.tryEvent(.startRoomFlow(roomID: roomID)) + stateMachine.tryEvent(.startRoomFlow(roomID: roomID, via: [], eventID: nil)) case .startCall(let roomProxy): actionsSubject.send(.presentCallScreen(roomProxy: roomProxy)) case .verifyUser(let userID): @@ -220,9 +242,10 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { } .store(in: &cancellables) - navigationStackCoordinator.push(coordinator) { [weak self] in + navigationStackCoordinator.push(coordinator, animated: animated) { [weak self] in guard let self else { return } - if entryPoint == .roomMember(userID: userID) { + if case let .roomMemberDetails(_, previousState) = stateMachine.state, + previousState == .initial { actionsSubject.send(.finished) } else { stateMachine.tryEvent(.dismissedRoomMemberDetails) @@ -271,7 +294,7 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { switch action { case .openDirectChat(let roomID): - stateMachine.tryEvent(.startRoomFlow(roomID: roomID)) + stateMachine.tryEvent(.startRoomFlow(roomID: roomID, via: [], eventID: nil)) case .startCall(let roomProxy): actionsSubject.send(.presentCallScreen(roomProxy: roomProxy)) case .dismiss: @@ -290,7 +313,7 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { } } - private func startRoomFlow(roomID: String) { + private func startRoomFlow(roomID: String, via: [String], eventID: String?, animated: Bool) { let coordinator = RoomFlowCoordinator(roomID: roomID, isChildFlow: true, navigationStackCoordinator: navigationStackCoordinator, @@ -313,6 +336,10 @@ final class RoomMembersFlowCoordinator: FlowCoordinatorProtocol { .store(in: &cancellables) roomFlowCoordinator = coordinator - coordinator.handleAppRoute(.room(roomID: roomID, via: []), animated: true) + if let eventID { + coordinator.handleAppRoute(.event(eventID: eventID, roomID: roomID, via: via), animated: animated) + } else { + coordinator.handleAppRoute(.room(roomID: roomID, via: via), animated: animated) + } } } diff --git a/ElementX/Sources/FlowCoordinators/SpaceFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/SpaceFlowCoordinator.swift index b6aa7df70..72d03e184 100644 --- a/ElementX/Sources/FlowCoordinators/SpaceFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/SpaceFlowCoordinator.swift @@ -373,6 +373,7 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol { private func startMembersFlow(roomProxy: JoinedRoomProxyProtocol) async { let flowCoordinator = RoomMembersFlowCoordinator(entryPoint: .roomMembersList, + animatedEntry: true, roomProxy: roomProxy, navigationStackCoordinator: navigationStackCoordinator, flowParameters: flowParameters)