diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionsFlow/Coordinator/UserSessionsFlowCoordinator.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionsFlow/Coordinator/UserSessionsFlowCoordinator.swift new file mode 100644 index 000000000..42151e7cf --- /dev/null +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionsFlow/Coordinator/UserSessionsFlowCoordinator.swift @@ -0,0 +1,76 @@ +// +// Copyright 2022 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 CommonKit + +struct UserSessionsFlowCoordinatorParameters { + let session: MXSession + let router: NavigationRouterType? +} + +final class UserSessionsFlowCoordinator: Coordinator, Presentable { + + // MARK: - Properties + + // MARK: Private + + private let parameters: UserSessionsFlowCoordinatorParameters + private let navigationRouter: NavigationRouterType + + // MARK: Public + + // Must be used only internally + var childCoordinators: [Coordinator] = [] + var completion: (() -> Void)? + + // MARK: - Setup + + init(parameters: UserSessionsFlowCoordinatorParameters) { + self.parameters = parameters + + self.navigationRouter = parameters.router ?? NavigationRouter(navigationController: RiotNavigationController()) + } + + // MARK: - Public + + func start() { + MXLog.debug("[UserSessionsFlowCoordinator] did start.") + + let rootCoordinatorParameters = UserSessionsOverviewCoordinatorParameters(session: self.parameters.session) + + let rootCoordinator = UserSessionsOverviewCoordinator(parameters: rootCoordinatorParameters) + + rootCoordinator.start() + + self.add(childCoordinator: rootCoordinator) + + if self.navigationRouter.modules.isEmpty == false { + self.navigationRouter.push(rootCoordinator, animated: true, popCompletion: { [weak self] in + self?.remove(childCoordinator: rootCoordinator) + self?.completion?() + }) + } else { + self.navigationRouter.setRootModule(rootCoordinator) { [weak self] in + self?.remove(childCoordinator: rootCoordinator) + self?.completion?() + } + } + } + + func toPresentable() -> UIViewController { + return self.navigationRouter.toPresentable() + } +} diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionsFlow/Coordinator/UserSessionsFlowCoordinatorBridgePresenter.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionsFlow/Coordinator/UserSessionsFlowCoordinatorBridgePresenter.swift new file mode 100644 index 000000000..d2a1a9ff0 --- /dev/null +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionsFlow/Coordinator/UserSessionsFlowCoordinatorBridgePresenter.swift @@ -0,0 +1,83 @@ +/* + Copyright 2022 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 +import UIKit + +/// UserSessionsFlowCoordinatorBridgePresenter enables to start UserSessionsFlowCoordinator from a view controller. +/// This bridge is used while waiting for global usage of coordinator pattern. +/// **WARNING**: This class breaks the Coordinator abstraction and it has been introduced for **Objective-C compatibility only** (mainly for integration in legacy view controllers). +/// Each bridge should be removed once the underlying Coordinator has been integrated by another Coordinator. +@objcMembers +final class UserSessionsFlowCoordinatorBridgePresenter: NSObject { + + // MARK: - Constants + + // MARK: - Properties + + // MARK: Private + + private let mxSession: MXSession + private var coordinator: UserSessionsFlowCoordinator? + + // MARK: Public + + var completion: (() -> Void)? + + // MARK: - Setup + + init(mxSession: MXSession) { + self.mxSession = mxSession + super.init() + } + + // MARK: - Public + + func push(from navigationController: UINavigationController, animated: Bool) { + + self.startUserSessionsFlow(mxSession: self.mxSession, navigationController: navigationController) + } + + // MARK: - Private + + private func startUserSessionsFlow(mxSession: MXSession, navigationController: UINavigationController?) { + + var navigationRouter: NavigationRouterType? + + if let navigationController = navigationController { + navigationRouter = NavigationRouterStore.shared.navigationRouter(for: navigationController) + } + + let coordinatorParameters = UserSessionsFlowCoordinatorParameters(session: mxSession, router: navigationRouter) + + let userSessionsFlowCoordinator = UserSessionsFlowCoordinator(parameters: coordinatorParameters) + + userSessionsFlowCoordinator.completion = { [weak self] in + + guard let self = self else { + return + } + + self.completion?() + self.coordinator = nil + } + + userSessionsFlowCoordinator.start() + + self.coordinator = userSessionsFlowCoordinator + } +}