Handle in-timeline permalinks to spaces
This will continue the RoomFlow with a SpaceFlow, fetch the SpaceRoomList from the SpaceService and render its rooms.
This commit is contained in:
committed by
Stefan Ceriu
parent
19bf29e854
commit
eeed91a64e
@@ -79,6 +79,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
private var mediaEventsTimelineFlowCoordinator: MediaEventsTimelineFlowCoordinator?
|
||||
// periphery:ignore - used to avoid deallocation
|
||||
private var childRoomFlowCoordinator: RoomFlowCoordinator?
|
||||
// periphery:ignore - retaining purpose
|
||||
private var spaceFlowCoordinator: SpaceFlowCoordinator?
|
||||
|
||||
private let stateMachine: StateMachine<State, Event> = .init(state: .initial)
|
||||
|
||||
@@ -257,24 +259,36 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
switch room {
|
||||
case .joined(let roomProxy):
|
||||
await storeAndSubscribeToRoomProxy(roomProxy)
|
||||
guard case let .eventFocus(focusEvent) = presentationAction else {
|
||||
// If is not a focus event just handle the presentation action directly in `presentRoom`
|
||||
stateMachine.tryEvent(.presentRoom(presentationAction: presentationAction), userInfo: EventUserInfo(animated: animated))
|
||||
return
|
||||
}
|
||||
// Otherwise check if the focussed event exists to handle a possible error or theaded event.
|
||||
switch await roomProxy.loadOrFetchEventDetails(for: focusEvent.eventID) {
|
||||
case .success(let event):
|
||||
if flowParameters.appSettings.threadsEnabled, let threadRootEventID = event.threadRootEventId() {
|
||||
stateMachine.tryEvent(.presentRoom(presentationAction: .eventFocus(.init(eventID: threadRootEventID, shouldSetPin: false))), userInfo: EventUserInfo(animated: animated))
|
||||
stateMachine.tryEvent(.presentThread(threadRootEventID: threadRootEventID, focusEventID: focusEvent.eventID), userInfo: EventUserInfo(animated: false))
|
||||
} else {
|
||||
stateMachine.tryEvent(.presentRoom(presentationAction: presentationAction), userInfo: EventUserInfo(animated: animated))
|
||||
if roomProxy.infoPublisher.value.isSpace {
|
||||
switch await userSession.clientProxy.spaceService.spaceRoomList(spaceID: roomProxy.id, parent: nil) {
|
||||
case .success(let spaceRoomListProxy):
|
||||
actionsSubject.send(.continueWithSpaceFlow(spaceRoomListProxy))
|
||||
case .failure:
|
||||
showErrorIndicator()
|
||||
stateMachine.tryEvent(.dismissFlow)
|
||||
}
|
||||
} else {
|
||||
await storeAndSubscribeToRoomProxy(roomProxy)
|
||||
|
||||
guard case let .eventFocus(focusEvent) = presentationAction else {
|
||||
// If is not a focus event just handle the presentation action directly in `presentRoom`
|
||||
stateMachine.tryEvent(.presentRoom(presentationAction: presentationAction), userInfo: EventUserInfo(animated: animated))
|
||||
return
|
||||
}
|
||||
|
||||
// Otherwise check if the focussed event exists to handle a possible error or theaded event.
|
||||
switch await roomProxy.loadOrFetchEventDetails(for: focusEvent.eventID) {
|
||||
case .success(let event):
|
||||
if flowParameters.appSettings.threadsEnabled, let threadRootEventID = event.threadRootEventId() {
|
||||
stateMachine.tryEvent(.presentRoom(presentationAction: .eventFocus(.init(eventID: threadRootEventID, shouldSetPin: false))), userInfo: EventUserInfo(animated: animated))
|
||||
stateMachine.tryEvent(.presentThread(threadRootEventID: threadRootEventID, focusEventID: focusEvent.eventID), userInfo: EventUserInfo(animated: false))
|
||||
} else {
|
||||
stateMachine.tryEvent(.presentRoom(presentationAction: presentationAction), userInfo: EventUserInfo(animated: animated))
|
||||
}
|
||||
case .failure:
|
||||
showErrorIndicator()
|
||||
stateMachine.tryEvent(.presentRoom(presentationAction: nil), userInfo: EventUserInfo(animated: animated))
|
||||
}
|
||||
case .failure:
|
||||
showErrorIndicator()
|
||||
stateMachine.tryEvent(.presentRoom(presentationAction: nil), userInfo: EventUserInfo(animated: animated))
|
||||
}
|
||||
default:
|
||||
stateMachine.tryEvent(.presentJoinRoomScreen(via: via), userInfo: EventUserInfo(animated: animated))
|
||||
@@ -322,7 +336,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
// swiftlint:disable:next function_body_length cyclomatic_complexity
|
||||
private func setupStateMachine() {
|
||||
addRouteMapping(stateMachine: stateMachine)
|
||||
|
||||
@@ -353,6 +367,14 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
// Thread + Room
|
||||
|
||||
case (_, .startSpaceFlow, .spaceFlow):
|
||||
guard let spaceRoomListProxy = (context.userInfo as? EventUserInfo)?.spaceRoomListProxy else {
|
||||
fatalError("The space room list proxy is required to present a space.")
|
||||
}
|
||||
startSpaceFlow(spaceRoomListProxy: spaceRoomListProxy, animated: animated)
|
||||
case (.spaceFlow, .finishedSpaceFlow, _):
|
||||
spaceFlowCoordinator = nil
|
||||
|
||||
case (_, .presentReportContent, .reportContent(let itemID, let senderID, _)):
|
||||
presentReportContent(for: itemID, from: senderID)
|
||||
|
||||
@@ -1521,7 +1543,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case .verifyUser(let userID):
|
||||
actionsSubject.send(.verifyUser(userID: userID))
|
||||
case .continueWithSpaceFlow(let spaceRoomListProxy):
|
||||
#warning("Present the space as a child.")
|
||||
stateMachine.tryEvent(.startSpaceFlow, userInfo: EventUserInfo(animated: true, spaceRoomListProxy: spaceRoomListProxy))
|
||||
case .finished:
|
||||
stateMachine.tryEvent(.dismissChildFlow)
|
||||
}
|
||||
@@ -1610,6 +1632,31 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
flowCoordinator.start()
|
||||
}
|
||||
|
||||
private func startSpaceFlow(spaceRoomListProxy: SpaceRoomListProxyProtocol, animated: Bool) {
|
||||
let coordinator = SpaceFlowCoordinator(entryPoint: .space(spaceRoomListProxy),
|
||||
spaceServiceProxy: userSession.clientProxy.spaceService,
|
||||
isChildFlow: true,
|
||||
navigationStackCoordinator: navigationStackCoordinator,
|
||||
flowParameters: flowParameters)
|
||||
coordinator.actionsPublisher
|
||||
.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .presentCallScreen(let roomProxy):
|
||||
actionsSubject.send(.presentCallScreen(roomProxy: roomProxy))
|
||||
case .verifyUser(let userID):
|
||||
actionsSubject.send(.verifyUser(userID: userID))
|
||||
case .finished:
|
||||
stateMachine.tryEvent(.finishedSpaceFlow)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
spaceFlowCoordinator = coordinator
|
||||
|
||||
coordinator.start()
|
||||
}
|
||||
|
||||
private static let loadingIndicatorID = "\(RoomFlowCoordinator.self)-Loading"
|
||||
|
||||
private func showLoadingIndicator(delay: Duration? = nil,
|
||||
|
||||
@@ -79,6 +79,9 @@ extension RoomFlowCoordinator {
|
||||
case presentingChild(childRoomID: String, previousState: State)
|
||||
/// The flow is complete and is handing control of the stack back to its parent.
|
||||
case complete
|
||||
|
||||
/// A space flow is in progress
|
||||
case spaceFlow(previousState: State)
|
||||
}
|
||||
|
||||
struct EventUserInfo {
|
||||
@@ -98,6 +101,9 @@ extension RoomFlowCoordinator {
|
||||
case presentThread(threadRootEventID: String, focusEventID: String?)
|
||||
case dismissThread
|
||||
|
||||
case startSpaceFlow
|
||||
case finishedSpaceFlow
|
||||
|
||||
case presentReportContent(itemID: TimelineItemIdentifier, senderID: String)
|
||||
case dismissReportContent
|
||||
|
||||
@@ -341,6 +347,11 @@ extension RoomFlowCoordinator {
|
||||
return .presentingChild(childRoomID: roomID, previousState: fromState)
|
||||
case (.presentingChild(_, let previousState), .dismissChildFlow):
|
||||
return previousState
|
||||
|
||||
case (.presentingChild(_, let previousState), .startSpaceFlow):
|
||||
return .spaceFlow(previousState: previousState)
|
||||
case (.spaceFlow(let previousState), .finishedSpaceFlow):
|
||||
return previousState
|
||||
|
||||
case (_, .presentRoomMemberDetails(userID: let userID)):
|
||||
return .roomMemberDetails(userID: userID, previousState: fromState)
|
||||
|
||||
Reference in New Issue
Block a user