Create ShowDirectory module

This commit is contained in:
ismailgulek
2020-09-10 12:50:26 +03:00
parent 9f42f0f522
commit 595ac3e021
12 changed files with 797 additions and 0 deletions
@@ -0,0 +1,71 @@
// File created from ScreenTemplate
// $ createScreen.sh Rooms2/ShowDirectory ShowDirectory
/*
Copyright 2020 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 UIKit
final class ShowDirectoryCoordinator: ShowDirectoryCoordinatorType {
// MARK: - Properties
// MARK: Private
private let session: MXSession
private var showDirectoryViewModel: ShowDirectoryViewModelType
private let showDirectoryViewController: ShowDirectoryViewController
// MARK: Public
// Must be used only internally
var childCoordinators: [Coordinator] = []
weak var delegate: ShowDirectoryCoordinatorDelegate?
// MARK: - Setup
init(session: MXSession) {
self.session = session
let showDirectoryViewModel = ShowDirectoryViewModel(session: self.session)
let showDirectoryViewController = ShowDirectoryViewController.instantiate(with: showDirectoryViewModel)
self.showDirectoryViewModel = showDirectoryViewModel
self.showDirectoryViewController = showDirectoryViewController
}
// MARK: - Public methods
func start() {
self.showDirectoryViewModel.coordinatorDelegate = self
}
func toPresentable() -> UIViewController {
return self.showDirectoryViewController
}
}
// MARK: - ShowDirectoryViewModelCoordinatorDelegate
extension ShowDirectoryCoordinator: ShowDirectoryViewModelCoordinatorDelegate {
func showDirectoryViewModel(_ viewModel: ShowDirectoryViewModelType, didCompleteWithUserDisplayName userDisplayName: String?) {
self.delegate?.showDirectoryCoordinator(self, didCompleteWithUserDisplayName: userDisplayName)
}
func showDirectoryViewModelDidCancel(_ viewModel: ShowDirectoryViewModelType) {
self.delegate?.showDirectoryCoordinatorDidCancel(self)
}
}
@@ -0,0 +1,29 @@
// File created from ScreenTemplate
// $ createScreen.sh Rooms2/ShowDirectory ShowDirectory
/*
Copyright 2020 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
protocol ShowDirectoryCoordinatorDelegate: class {
func showDirectoryCoordinator(_ coordinator: ShowDirectoryCoordinatorType, didCompleteWithUserDisplayName userDisplayName: String?)
func showDirectoryCoordinatorDidCancel(_ coordinator: ShowDirectoryCoordinatorType)
}
/// `ShowDirectoryCoordinatorType` is a protocol describing a Coordinator that handle key backup setup passphrase navigation flow.
protocol ShowDirectoryCoordinatorType: Coordinator, Presentable {
var delegate: ShowDirectoryCoordinatorDelegate? { get }
}
@@ -0,0 +1,26 @@
// File created from ScreenTemplate
// $ createScreen.sh Rooms2/ShowDirectory ShowDirectory
/*
Copyright 2020 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
/// ShowDirectoryViewController view actions exposed to view model
enum ShowDirectoryViewAction {
case loadData
case complete
case cancel
}
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="V8j-Lb-PgC">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Template Screen View Controller-->
<scene sceneID="mt5-wz-YKA">
<objects>
<viewController extendedLayoutIncludesOpaqueBars="YES" automaticallyAdjustsScrollViewInsets="NO" id="V8j-Lb-PgC" customClass="ShowDirectoryViewController" customModule="Riot" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="EL9-GA-lwo">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9U2-KL-ZVA">
<rect key="frame" x="0.0" y="44" width="414" height="852"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="e7g-um-WO4">
<rect key="frame" x="0.0" y="0.0" width="414" height="208"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="voD-3Q-ryt">
<rect key="frame" x="0.0" y="0.0" width="414" height="208"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="A message" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bxI-mu-qng">
<rect key="frame" x="20" y="40" width="374" height="18"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DOt-5E-FjF">
<rect key="frame" x="20" y="158" width="374" height="30"/>
<state key="normal" title="OK"/>
<connections>
<action selector="doneButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="uvI-tt-Nfj"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="bxI-mu-qng" secondAttribute="trailing" constant="20" id="2v5-vH-NEd"/>
<constraint firstItem="DOt-5E-FjF" firstAttribute="top" secondItem="bxI-mu-qng" secondAttribute="bottom" constant="100" id="C4r-0w-VXj"/>
<constraint firstItem="bxI-mu-qng" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" constant="20" id="I1A-QW-IJG"/>
<constraint firstAttribute="trailing" secondItem="DOt-5E-FjF" secondAttribute="trailing" constant="20" id="NKP-2G-Czj"/>
<constraint firstItem="bxI-mu-qng" firstAttribute="top" secondItem="voD-3Q-ryt" secondAttribute="top" constant="40" id="bU7-a2-LIj"/>
<constraint firstAttribute="bottom" secondItem="DOt-5E-FjF" secondAttribute="bottom" constant="20" id="dmC-vE-FeB"/>
<constraint firstItem="DOt-5E-FjF" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" constant="20" id="flU-tM-8hK"/>
<constraint firstAttribute="width" priority="750" constant="500" id="glD-Sz-73O"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="voD-3Q-ryt" secondAttribute="bottom" id="63a-5e-ptU"/>
<constraint firstItem="voD-3Q-ryt" firstAttribute="centerX" secondItem="e7g-um-WO4" secondAttribute="centerX" id="P2G-mq-gQW"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="voD-3Q-ryt" secondAttribute="trailing" id="QgV-SO-5yf"/>
<constraint firstItem="voD-3Q-ryt" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="e7g-um-WO4" secondAttribute="leading" id="YPo-u1-PtT"/>
<constraint firstItem="voD-3Q-ryt" firstAttribute="top" secondItem="e7g-um-WO4" secondAttribute="top" id="rhQ-96-szL"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="e7g-um-WO4" secondAttribute="trailing" id="GyG-Fh-PME"/>
<constraint firstItem="e7g-um-WO4" firstAttribute="width" secondItem="9U2-KL-ZVA" secondAttribute="width" id="Ok2-WQ-Zgc"/>
<constraint firstAttribute="bottom" secondItem="e7g-um-WO4" secondAttribute="bottom" id="Y46-NP-zAc"/>
<constraint firstItem="e7g-um-WO4" firstAttribute="leading" secondItem="9U2-KL-ZVA" secondAttribute="leading" id="aoV-Yh-AcD"/>
<constraint firstItem="e7g-um-WO4" firstAttribute="top" secondItem="9U2-KL-ZVA" secondAttribute="top" id="pFN-bA-SHw"/>
</constraints>
</scrollView>
</subviews>
<color key="backgroundColor" red="0.94509803921568625" green="0.96078431372549022" blue="0.97254901960784312" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="9U2-KL-ZVA" secondAttribute="bottom" id="7Cb-nY-CsO"/>
<constraint firstItem="9U2-KL-ZVA" firstAttribute="leading" secondItem="bFg-jh-JZB" secondAttribute="leading" id="GdQ-hK-muG"/>
<constraint firstItem="bFg-jh-JZB" firstAttribute="trailing" secondItem="9U2-KL-ZVA" secondAttribute="trailing" id="sbD-ek-vGJ"/>
<constraint firstItem="bFg-jh-JZB" firstAttribute="top" secondItem="9U2-KL-ZVA" secondAttribute="top" id="wTB-V6-IHV"/>
</constraints>
<viewLayoutGuide key="safeArea" id="bFg-jh-JZB"/>
</view>
<connections>
<outlet property="doneButton" destination="DOt-5E-FjF" id="ktw-U4-efQ"/>
<outlet property="informationLabel" destination="bxI-mu-qng" id="pbX-aZ-inC"/>
<outlet property="scrollView" destination="9U2-KL-ZVA" id="ojG-2y-X7b"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="zK0-v6-7Wt" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-3198" y="-647"/>
</scene>
</scenes>
</document>
@@ -0,0 +1,178 @@
// File created from ScreenTemplate
// $ createScreen.sh Rooms2/ShowDirectory ShowDirectory
/*
Copyright 2020 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 UIKit
final class ShowDirectoryViewController: UIViewController {
// MARK: - Constants
private enum Constants {
static let aConstant: Int = 666
}
// MARK: - Properties
// MARK: Outlets
@IBOutlet private weak var scrollView: UIScrollView!
@IBOutlet private weak var informationLabel: UILabel!
@IBOutlet private weak var doneButton: UIButton!
// MARK: Private
private var viewModel: ShowDirectoryViewModelType!
private var theme: Theme!
private var keyboardAvoider: KeyboardAvoider?
private var errorPresenter: MXKErrorPresentation!
private var activityPresenter: ActivityIndicatorPresenter!
// MARK: - Setup
class func instantiate(with viewModel: ShowDirectoryViewModelType) -> ShowDirectoryViewController {
let viewController = StoryboardScene.ShowDirectoryViewController.initialScene.instantiate()
viewController.viewModel = viewModel
viewController.theme = ThemeService.shared().theme
return viewController
}
// MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.setupViews()
self.keyboardAvoider = KeyboardAvoider(scrollViewContainerView: self.view, scrollView: self.scrollView)
self.activityPresenter = ActivityIndicatorPresenter()
self.errorPresenter = MXKErrorAlertPresentation()
self.registerThemeServiceDidChangeThemeNotification()
self.update(theme: self.theme)
self.viewModel.viewDelegate = self
self.viewModel.process(viewAction: .loadData)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.keyboardAvoider?.startAvoiding()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.keyboardAvoider?.stopAvoiding()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return self.theme.statusBarStyle
}
// MARK: - Private
private func update(theme: Theme) {
self.theme = theme
self.view.backgroundColor = theme.headerBackgroundColor
if let navigationBar = self.navigationController?.navigationBar {
theme.applyStyle(onNavigationBar: navigationBar)
}
// TODO: Set view colors here
self.informationLabel.textColor = theme.textPrimaryColor
self.doneButton.backgroundColor = theme.backgroundColor
theme.applyStyle(onButton: self.doneButton)
}
private func registerThemeServiceDidChangeThemeNotification() {
NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange), name: .themeServiceDidChangeTheme, object: nil)
}
@objc private func themeDidChange() {
self.update(theme: ThemeService.shared().theme)
}
private func setupViews() {
let cancelBarButtonItem = MXKBarButtonItem(title: VectorL10n.cancel, style: .plain) { [weak self] in
self?.cancelButtonAction()
}
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
self.title = "Template"
self.scrollView.keyboardDismissMode = .interactive
self.informationLabel.text = "VectorL10n.showDirectoryTitle"
}
private func render(viewState: ShowDirectoryViewState) {
switch viewState {
case .loading:
self.renderLoading()
case .loaded(let displayName):
self.renderLoaded(displayName: displayName)
case .error(let error):
self.render(error: error)
}
}
private func renderLoading() {
self.activityPresenter.presentActivityIndicator(on: self.view, animated: true)
self.informationLabel.text = "Fetch display name"
}
private func renderLoaded(displayName: String) {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
self.informationLabel.text = "You display name: \(displayName)"
}
private func render(error: Error) {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
self.errorPresenter.presentError(from: self, forError: error, animated: true, handler: nil)
}
// MARK: - Actions
@IBAction private func doneButtonAction(_ sender: Any) {
self.viewModel.process(viewAction: .complete)
}
private func cancelButtonAction() {
self.viewModel.process(viewAction: .cancel)
}
}
// MARK: - ShowDirectoryViewModelViewDelegate
extension ShowDirectoryViewController: ShowDirectoryViewModelViewDelegate {
func showDirectoryViewModel(_ viewModel: ShowDirectoryViewModelType, didUpdateViewState viewSate: ShowDirectoryViewState) {
self.render(viewState: viewSate)
}
}
@@ -0,0 +1,91 @@
// File created from ScreenTemplate
// $ createScreen.sh Rooms2/ShowDirectory ShowDirectory
/*
Copyright 2020 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
final class ShowDirectoryViewModel: ShowDirectoryViewModelType {
// MARK: - Properties
// MARK: Private
private let session: MXSession
private var currentOperation: MXHTTPOperation?
private var userDisplayName: String?
// MARK: Public
weak var viewDelegate: ShowDirectoryViewModelViewDelegate?
weak var coordinatorDelegate: ShowDirectoryViewModelCoordinatorDelegate?
// MARK: - Setup
init(session: MXSession) {
self.session = session
}
deinit {
self.cancelOperations()
}
// MARK: - Public
func process(viewAction: ShowDirectoryViewAction) {
switch viewAction {
case .loadData:
self.loadData()
case .complete:
self.coordinatorDelegate?.showDirectoryViewModel(self, didCompleteWithUserDisplayName: self.userDisplayName)
case .cancel:
self.cancelOperations()
self.coordinatorDelegate?.showDirectoryViewModelDidCancel(self)
}
}
// MARK: - Private
private func loadData() {
self.update(viewState: .loading)
// Check first that the user homeserver is federated with the Riot-bot homeserver
self.currentOperation = self.session.matrixRestClient.displayName(forUser: self.session.myUser.userId) { [weak self] (response) in
guard let self = self else {
return
}
switch response {
case .success(let userDisplayName):
self.update(viewState: .loaded(userDisplayName))
self.userDisplayName = userDisplayName
case .failure(let error):
self.update(viewState: .error(error))
}
}
}
private func update(viewState: ShowDirectoryViewState) {
self.viewDelegate?.showDirectoryViewModel(self, didUpdateViewState: viewState)
}
private func cancelOperations() {
self.currentOperation?.cancel()
}
}
@@ -0,0 +1,37 @@
// File created from ScreenTemplate
// $ createScreen.sh Rooms2/ShowDirectory ShowDirectory
/*
Copyright 2020 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
protocol ShowDirectoryViewModelViewDelegate: class {
func showDirectoryViewModel(_ viewModel: ShowDirectoryViewModelType, didUpdateViewState viewSate: ShowDirectoryViewState)
}
protocol ShowDirectoryViewModelCoordinatorDelegate: class {
func showDirectoryViewModel(_ viewModel: ShowDirectoryViewModelType, didCompleteWithUserDisplayName userDisplayName: String?)
func showDirectoryViewModelDidCancel(_ viewModel: ShowDirectoryViewModelType)
}
/// Protocol describing the view model used by `ShowDirectoryViewController`
protocol ShowDirectoryViewModelType {
var viewDelegate: ShowDirectoryViewModelViewDelegate? { get set }
var coordinatorDelegate: ShowDirectoryViewModelCoordinatorDelegate? { get set }
func process(viewAction: ShowDirectoryViewAction)
}
@@ -0,0 +1,26 @@
// File created from ScreenTemplate
// $ createScreen.sh Rooms2/ShowDirectory ShowDirectory
/*
Copyright 2020 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
/// ShowDirectoryViewController view state
enum ShowDirectoryViewState {
case loading
case loaded(_ displayName: String)
case error(Error)
}
@@ -0,0 +1,80 @@
// File created from FlowTemplate
// $ createRootCoordinator.sh Rooms2 ShowDirectory ShowDirectory
/*
Copyright 2020 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 UIKit
@objcMembers
final class ShowDirectoryCoordinator: ShowDirectoryCoordinatorType {
// MARK: - Properties
// MARK: Private
private let navigationRouter: NavigationRouterType
private let session: MXSession
// MARK: Public
// Must be used only internally
var childCoordinators: [Coordinator] = []
weak var delegate: ShowDirectoryCoordinatorDelegate?
// MARK: - Setup
init(session: MXSession) {
self.navigationRouter = NavigationRouter(navigationController: RiotNavigationController())
self.session = session
}
// MARK: - Public methods
func start() {
let rootCoordinator = self.createShowDirectoryCoordinator()
rootCoordinator.start()
self.add(childCoordinator: rootCoordinator)
self.navigationRouter.setRootModule(rootCoordinator)
}
func toPresentable() -> UIViewController {
return self.navigationRouter.toPresentable()
}
// MARK: - Private methods
private func createShowDirectoryCoordinator() -> ShowDirectoryCoordinator {
let coordinator = ShowDirectoryCoordinator(session: self.session)
coordinator.delegate = self
return coordinator
}
}
// MARK: - ShowDirectoryCoordinatorDelegate
extension ShowDirectoryCoordinator: ShowDirectoryCoordinatorDelegate {
func showDirectoryCoordinator(_ coordinator: ShowDirectoryCoordinatorType, didCompleteWithUserDisplayName userDisplayName: String?) {
self.delegate?.showDirectoryCoordinatorDidComplete(self)
}
func showDirectoryCoordinatorDidCancel(_ coordinator: ShowDirectoryCoordinatorType) {
self.delegate?.showDirectoryCoordinatorDidComplete(self)
}
}
@@ -0,0 +1,83 @@
// File created from FlowTemplate
// $ createRootCoordinator.sh Rooms2 ShowDirectory ShowDirectory
/*
Copyright 2020 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
@objc protocol ShowDirectoryCoordinatorBridgePresenterDelegate {
func showDirectoryCoordinatorBridgePresenterDelegateDidComplete(_ coordinatorBridgePresenter: ShowDirectoryCoordinatorBridgePresenter)
}
/// ShowDirectoryCoordinatorBridgePresenter enables to start ShowDirectoryCoordinator from a view controller.
/// This bridge is used while waiting for global usage of coordinator pattern.
@objcMembers
final class ShowDirectoryCoordinatorBridgePresenter: NSObject {
// MARK: - Properties
// MARK: Private
private let session: MXSession
private var coordinator: ShowDirectoryCoordinator?
// MARK: Public
weak var delegate: ShowDirectoryCoordinatorBridgePresenterDelegate?
// MARK: - Setup
init(session: MXSession) {
self.session = session
super.init()
}
// MARK: - Public
// NOTE: Default value feature is not compatible with Objective-C.
// func present(from viewController: UIViewController, animated: Bool) {
// self.present(from: viewController, animated: animated)
// }
func present(from viewController: UIViewController, animated: Bool) {
let showDirectoryCoordinator = ShowDirectoryCoordinator(session: self.session)
showDirectoryCoordinator.delegate = self
viewController.present(showDirectoryCoordinator.toPresentable(), animated: animated, completion: nil)
showDirectoryCoordinator.start()
self.coordinator = showDirectoryCoordinator
}
func dismiss(animated: Bool, completion: (() -> Void)?) {
guard let coordinator = self.coordinator else {
return
}
coordinator.toPresentable().dismiss(animated: animated) {
self.coordinator = nil
if let completion = completion {
completion()
}
}
}
}
// MARK: - ShowDirectoryCoordinatorDelegate
extension ShowDirectoryCoordinatorBridgePresenter: ShowDirectoryCoordinatorDelegate {
func showDirectoryCoordinatorDidComplete(_ coordinator: ShowDirectoryCoordinatorType) {
self.delegate?.showDirectoryCoordinatorBridgePresenterDelegateDidComplete(self)
}
}
@@ -0,0 +1,28 @@
// File created from FlowTemplate
// $ createRootCoordinator.sh Rooms2 ShowDirectory ShowDirectory
/*
Copyright 2020 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
protocol ShowDirectoryCoordinatorDelegate: class {
func showDirectoryCoordinatorDidComplete(_ coordinator: ShowDirectoryCoordinatorType)
}
/// `ShowDirectoryCoordinatorType` is a protocol describing a Coordinator that handle keybackup setup navigation flow.
protocol ShowDirectoryCoordinatorType: Coordinator, Presentable {
var delegate: ShowDirectoryCoordinatorDelegate? { get }
}