mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
implemented the basics of the flow coordinator, the logic and the navigation flow to get to the space settings view
This commit is contained in:
@@ -42,6 +42,7 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
private var childSpaceFlowCoordinator: SpaceFlowCoordinator?
|
||||
private var roomFlowCoordinator: RoomFlowCoordinator?
|
||||
private var membersFlowCoordinator: RoomMembersFlowCoordinator?
|
||||
private var settingsFlowCoordinator: SpaceSettingsFlowCoordinator?
|
||||
|
||||
indirect enum State: StateType {
|
||||
/// The state machine hasn't started.
|
||||
@@ -56,6 +57,8 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case roomFlow(previousState: State)
|
||||
/// A members flow is in progress
|
||||
case membersFlow
|
||||
/// A space settings flow is in progress
|
||||
case settingsFlow
|
||||
|
||||
case leftSpace
|
||||
}
|
||||
@@ -83,6 +86,9 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
case startMembersFlow
|
||||
case stopMembersFlow
|
||||
|
||||
case startSettingsFlow
|
||||
case stopSettingsFlow
|
||||
}
|
||||
|
||||
private let stateMachine: StateMachine<State, Event>
|
||||
@@ -142,6 +148,9 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case .membersFlow:
|
||||
membersFlowCoordinator?.clearRoute(animated: animated)
|
||||
clearRoute(animated: animated) // Re-run with the state machine back in the .space state.
|
||||
case .settingsFlow:
|
||||
settingsFlowCoordinator?.clearRoute(animated: animated)
|
||||
clearRoute(animated: animated) // Re-run with the state machine back in the .space state.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +221,7 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
guard let self, let roomProxy = context.userInfo as? JoinedRoomProxyProtocol else {
|
||||
fatalError("The room proxy must always be provided")
|
||||
}
|
||||
Task { await self.startMembersFlow(roomProxy: roomProxy) }
|
||||
startMembersFlow(roomProxy: roomProxy)
|
||||
}
|
||||
|
||||
stateMachine.addRouteMapping { event, fromState, _ in
|
||||
@@ -223,6 +232,22 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
membersFlowCoordinator = nil
|
||||
}
|
||||
|
||||
stateMachine.addRouteMapping { event, fromState, _ in
|
||||
guard event == .startSettingsFlow, case .space = fromState else { return nil }
|
||||
return .settingsFlow
|
||||
} handler: { [weak self] context in
|
||||
guard let self, let roomProxy = context.userInfo as? JoinedRoomProxyProtocol else { return }
|
||||
startSettingsFlow(roomProxy: roomProxy)
|
||||
}
|
||||
|
||||
stateMachine.addRouteMapping { event, fromState, _ in
|
||||
guard event == .stopSettingsFlow, case .settingsFlow = fromState else { return nil }
|
||||
return .space
|
||||
} handler: { [weak self] _ in
|
||||
guard let self else { return }
|
||||
settingsFlowCoordinator = nil
|
||||
}
|
||||
|
||||
stateMachine.addErrorHandler { context in
|
||||
fatalError("Unexpected transition: \(context)")
|
||||
}
|
||||
@@ -235,6 +260,7 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
spaceServiceProxy: spaceServiceProxy,
|
||||
selectedSpaceRoomPublisher: selectedSpaceRoomSubject.asCurrentValuePublisher(),
|
||||
userSession: flowParameters.userSession,
|
||||
appSettings: flowParameters.appSettings,
|
||||
userIndicatorController: flowParameters.userIndicatorController)
|
||||
let coordinator = SpaceScreenCoordinator(parameters: parameters)
|
||||
coordinator.actionsPublisher
|
||||
@@ -251,6 +277,8 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
stateMachine.tryEvent(.leftSpace)
|
||||
case .displayMembers(let roomProxy):
|
||||
stateMachine.tryEvent(.startMembersFlow, userInfo: roomProxy)
|
||||
case .displaySpaceSettings(roomProxy: let roomProxy):
|
||||
stateMachine.tryEvent(.startSettingsFlow, userInfo: roomProxy)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
@@ -372,7 +400,7 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
selectedSpaceRoomSubject.send(roomID)
|
||||
}
|
||||
|
||||
private func startMembersFlow(roomProxy: JoinedRoomProxyProtocol) async {
|
||||
private func startMembersFlow(roomProxy: JoinedRoomProxyProtocol) {
|
||||
let flowCoordinator = RoomMembersFlowCoordinator(entryPoint: .roomMembersList,
|
||||
roomProxy: roomProxy,
|
||||
navigationStackCoordinator: navigationStackCoordinator,
|
||||
@@ -393,4 +421,22 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
membersFlowCoordinator = flowCoordinator
|
||||
flowCoordinator.start()
|
||||
}
|
||||
|
||||
private func startSettingsFlow(roomProxy: JoinedRoomProxyProtocol) {
|
||||
let flowCoordinator = SpaceSettingsFlowCoordinator(roomProxy: roomProxy,
|
||||
navigationStackCoordinator: navigationStackCoordinator,
|
||||
flowParameters: flowParameters)
|
||||
|
||||
flowCoordinator.actions.sink { [weak self] actions in
|
||||
guard let self else { return }
|
||||
switch actions {
|
||||
case .finished:
|
||||
stateMachine.tryEvent(.stopSettingsFlow)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
settingsFlowCoordinator = flowCoordinator
|
||||
flowCoordinator.start()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
//
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import SwiftState
|
||||
|
||||
enum SpaceSettingsFlowCoordinatorAction {
|
||||
case finished
|
||||
}
|
||||
|
||||
final class SpaceSettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
indirect enum State: StateType {
|
||||
/// The state machine hasn't started.
|
||||
case initial
|
||||
/// The space settings screen
|
||||
case spaceSettings
|
||||
}
|
||||
|
||||
enum Event: EventType {
|
||||
case start
|
||||
|
||||
case presentSpaceSettings
|
||||
}
|
||||
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let navigationStackCoordinator: NavigationStackCoordinator
|
||||
private let flowParameters: CommonFlowParameters
|
||||
|
||||
private let stateMachine: StateMachine<State, Event>
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private let actionsSubject: PassthroughSubject<SpaceSettingsFlowCoordinatorAction, Never> = .init()
|
||||
var actions: AnyPublisher<SpaceSettingsFlowCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(roomProxy: JoinedRoomProxyProtocol,
|
||||
navigationStackCoordinator: NavigationStackCoordinator,
|
||||
flowParameters: CommonFlowParameters) {
|
||||
self.roomProxy = roomProxy
|
||||
self.flowParameters = flowParameters
|
||||
self.navigationStackCoordinator = navigationStackCoordinator
|
||||
|
||||
stateMachine = .init(state: .initial)
|
||||
configureStateMachine()
|
||||
}
|
||||
|
||||
func start(animated: Bool) {
|
||||
stateMachine.tryEvent(.presentSpaceSettings, userInfo: animated)
|
||||
}
|
||||
|
||||
func handleAppRoute(_ appRoute: AppRoute, animated: Bool) {
|
||||
fatalError("Not implemented yet")
|
||||
}
|
||||
|
||||
func clearRoute(animated: Bool) {
|
||||
// Not implemented yet
|
||||
}
|
||||
|
||||
private func configureStateMachine() {
|
||||
stateMachine.addRouteMapping { event, fromState, _ in
|
||||
switch (fromState, event) {
|
||||
case (.initial, .presentSpaceSettings):
|
||||
return .spaceSettings
|
||||
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
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, .presentSpaceSettings, .spaceSettings):
|
||||
presentSpaceSettings(animated: animated)
|
||||
|
||||
default:
|
||||
fatalError("Unhandled transition")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func presentSpaceSettings(animated: Bool) {
|
||||
let coordinator = SpaceSettingsScreenCoordinator(parameters: .init())
|
||||
|
||||
coordinator.actionsPublisher.sink { [weak self] action in
|
||||
switch action { }
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
navigationStackCoordinator.push(coordinator, animated: animated) { [weak self] in
|
||||
self?.actionsSubject.send(.finished)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user