Device Verification: Add DeviceVerificationDataLoading VC, a loading wheel VC

This commit is contained in:
manuroe
2019-04-17 12:47:42 +02:00
parent 26d9a5263c
commit 2cdcb2cca9
10 changed files with 285 additions and 45 deletions
@@ -69,45 +69,10 @@ final class DeviceVerificationCoordinator: DeviceVerificationCoordinatorType {
// MARK: - Public methods
func start() {
guard let otherUser = self.session.user(withUserId: otherUserId) else {
return // TODO
}
// Before starting make sure we have device crypto informatino
self.session.crypto?.downloadKeys([self.otherUserId], forceDownload: false, success: { [weak self] (usersDevicesMap) in
guard let sself = self else {
return
}
guard let otherDevice = usersDevicesMap?.object(forDevice: sself.otherDeviceId, forUser: sself.otherUserId) else {
return // TODO
}
var rootCoordinator: Coordinator & Presentable
if let incomingTransaction = sself.incomingTransaction {
let coordinator = sself.createDeviceVerificationIncomingCoordinator(otherUser: otherUser, transaction: incomingTransaction)
coordinator.delegate = self
rootCoordinator = coordinator
} else {
let coordinator = sself.createDeviceVerificationStartCoordinator(otherUser: otherUser, otherDevice: otherDevice)
coordinator.delegate = self
rootCoordinator = coordinator
}
// TODO: To remove. Only for dev
//rootCoordinator = DeviceVerificationVerifyCoordinator(session: sself.session)
//rootCoordinator.delegate = self
rootCoordinator.start()
sself.add(childCoordinator: rootCoordinator)
sself.navigationRouter.setRootModule(rootCoordinator)
}, failure: { (error) in
// TODO
})
}
let rootViewController = self.createDataLoadingViewController()
rootViewController.delegate = self
self.navigationRouter.setRootModule(rootViewController)
}
func toPresentable() -> UIViewController {
return self.navigationRouter.toPresentable()
@@ -115,16 +80,28 @@ final class DeviceVerificationCoordinator: DeviceVerificationCoordinatorType {
// MARK: - Private methods
private func createDeviceVerificationStartCoordinator(otherUser: MXUser, otherDevice: MXDeviceInfo) -> DeviceVerificationStartCoordinator {
let coordinator = DeviceVerificationStartCoordinator(session: self.session, otherUser: otherUser, otherDevice: otherDevice)
coordinator.delegate = self
return coordinator
private func createDataLoadingViewController() -> DeviceVerificationDataLoadingViewController {
let viewController = DeviceVerificationDataLoadingViewController.instantiate(session: self.session, otherUserId: self.otherUserId, otherDeviceId: self.otherDeviceId)
viewController.delegate = self
return viewController
}
private func createDeviceVerificationIncomingCoordinator(otherUser: MXUser, transaction: MXIncomingSASTransaction) -> DeviceVerificationIncomingCoordinator {
private func showStart(otherUser: MXUser, otherDevice: MXDeviceInfo) {
let coordinator = DeviceVerificationStartCoordinator(session: self.session, otherUser: otherUser, otherDevice: otherDevice)
coordinator.delegate = self
coordinator.start()
self.add(childCoordinator: coordinator)
self.navigationRouter.setRootModule(coordinator)
}
private func showIncoming(otherUser: MXUser, transaction: MXIncomingSASTransaction) {
let coordinator = DeviceVerificationIncomingCoordinator(session: self.session, otherUser: otherUser, transaction: transaction)
coordinator.delegate = self
return coordinator
coordinator.start()
self.add(childCoordinator: coordinator)
self.navigationRouter.setRootModule(coordinator)
}
private func showVerify(transaction: MXSASTransaction, animated: Bool) {
@@ -145,6 +122,21 @@ final class DeviceVerificationCoordinator: DeviceVerificationCoordinatorType {
}
}
extension DeviceVerificationCoordinator: DeviceVerificationDataLoadingViewControllerDelegate {
func deviceVerificationDataLoadingViewControllerDidLoadData(_ viewController: DeviceVerificationDataLoadingViewController, user: MXUser, device: MXDeviceInfo) {
if let incomingTransaction = self.incomingTransaction {
self.showIncoming(otherUser: user, transaction: incomingTransaction)
} else {
self.showStart(otherUser: user, otherDevice: device)
}
}
func deviceVerificationDataLoadingViewControllerDidCancel(_ viewController: DeviceVerificationDataLoadingViewController) {
self.delegate?.deviceVerificationCoordinatorDidComplete(self, otherUserId: self.otherUserId, otherDeviceId: self.otherDeviceId)
}
}
extension DeviceVerificationCoordinator: DeviceVerificationStartCoordinatorDelegate {
func deviceVerificationStartCoordinator(_ coordinator: DeviceVerificationStartCoordinatorType, didCompleteWithOutgoingTransaction transaction: MXSASTransaction) {
self.showVerify(transaction: transaction, animated: true)
@@ -69,6 +69,7 @@ final class DeviceVerificationIncomingViewController: UIViewController {
// Do any additional setup after loading the view.
self.title = VectorL10n.deviceVerificationTitle
self.vc_removeBackTitle()
self.setupViews()
self.keyboardAvoider = KeyboardAvoider(scrollViewContainerView: self.view, scrollView: self.scrollView)
@@ -0,0 +1,72 @@
<?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="dBQ-CG-VDL">
<device id="retina4_7" 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>
<!--Device Verification Data Loading View Controller-->
<scene sceneID="EyC-m5-6uM">
<objects>
<viewController extendedLayoutIncludesOpaqueBars="YES" automaticallyAdjustsScrollViewInsets="NO" id="dBQ-CG-VDL" customClass="DeviceVerificationDataLoadingViewController" customModule="Riot" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ht4-fu-3rS">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jOh-c7-uod">
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="c4q-B8-hPy">
<rect key="frame" x="0.0" y="0.0" width="375" height="428"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fNE-v3-2lx">
<rect key="frame" x="0.0" y="0.0" width="375" height="428"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="width" priority="750" constant="500" id="9am-iX-rzi"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="fNE-v3-2lx" firstAttribute="top" secondItem="c4q-B8-hPy" secondAttribute="top" id="bHO-0I-Jjh"/>
<constraint firstItem="fNE-v3-2lx" firstAttribute="centerX" secondItem="c4q-B8-hPy" secondAttribute="centerX" id="fGs-s5-GHA"/>
<constraint firstItem="fNE-v3-2lx" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="c4q-B8-hPy" secondAttribute="leading" id="jpJ-bp-Vmz"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="fNE-v3-2lx" secondAttribute="trailing" id="juO-Zk-MPs"/>
<constraint firstAttribute="bottom" secondItem="fNE-v3-2lx" secondAttribute="bottom" id="sZa-ea-aZQ"/>
<constraint firstAttribute="height" constant="428" id="vx4-4u-WS1"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="c4q-B8-hPy" secondAttribute="bottom" id="KlD-dP-EYo"/>
<constraint firstItem="c4q-B8-hPy" firstAttribute="width" secondItem="jOh-c7-uod" secondAttribute="width" id="Tly-og-biF"/>
<constraint firstAttribute="trailing" secondItem="c4q-B8-hPy" secondAttribute="trailing" id="fNe-8B-X6c"/>
<constraint firstItem="c4q-B8-hPy" firstAttribute="leading" secondItem="jOh-c7-uod" secondAttribute="leading" id="h5p-NS-unN"/>
<constraint firstItem="c4q-B8-hPy" firstAttribute="top" secondItem="jOh-c7-uod" secondAttribute="top" id="zPm-BG-Pm8"/>
</constraints>
</scrollView>
</subviews>
<color key="backgroundColor" red="0.94509803921568625" green="0.96078431372549022" blue="0.97254901960784312" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="jOh-c7-uod" secondAttribute="trailing" id="7K8-MG-xLT"/>
<constraint firstItem="6ex-OQ-2sZ" firstAttribute="bottom" secondItem="jOh-c7-uod" secondAttribute="bottom" id="DGP-MJ-g6l"/>
<constraint firstItem="jOh-c7-uod" firstAttribute="leading" secondItem="Ht4-fu-3rS" secondAttribute="leading" id="TGc-b5-uMu"/>
<constraint firstItem="6ex-OQ-2sZ" firstAttribute="leading" secondItem="jOh-c7-uod" secondAttribute="leading" id="Z7r-yd-J4e"/>
<constraint firstItem="jOh-c7-uod" firstAttribute="trailing" secondItem="6ex-OQ-2sZ" secondAttribute="trailing" id="jVN-Fr-MKN"/>
<constraint firstItem="jOh-c7-uod" firstAttribute="top" secondItem="6ex-OQ-2sZ" secondAttribute="top" id="s7K-jf-P1z"/>
</constraints>
<viewLayoutGuide key="safeArea" id="6ex-OQ-2sZ"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="bLY-II-iJ3" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-1703" y="255"/>
</scene>
</scenes>
</document>
@@ -0,0 +1,147 @@
// File created from simpleScreenTemplate
// $ createSimpleScreen.sh DeviceVerification/Loading DeviceVerificationDataLoading
/*
Copyright 2019 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
protocol DeviceVerificationDataLoadingViewControllerDelegate: class {
func deviceVerificationDataLoadingViewControllerDidLoadData(_ viewController: DeviceVerificationDataLoadingViewController, user: MXUser, device: MXDeviceInfo)
func deviceVerificationDataLoadingViewControllerDidCancel(_ viewController: DeviceVerificationDataLoadingViewController)
}
final class DeviceVerificationDataLoadingViewController: UIViewController {
// MARK: - Properties
// MARK: Outlets
// MARK: Private
private var session: MXSession!
private var otherUserId: String!
private var otherDeviceId: String!
private var theme: Theme!
private var errorPresenter: MXKErrorPresentation!
private var activityPresenter: ActivityIndicatorPresenter!
// MARK: Public
weak var delegate: DeviceVerificationDataLoadingViewControllerDelegate?
// MARK: - Setup
class func instantiate(session: MXSession, otherUserId: String, otherDeviceId: String) -> DeviceVerificationDataLoadingViewController {
let viewController = StoryboardScene.DeviceVerificationDataLoadingViewController.initialScene.instantiate()
viewController.session = session
viewController.otherUserId = otherUserId
viewController.otherDeviceId = otherDeviceId
viewController.theme = ThemeService.shared().theme
return viewController
}
// MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.title = VectorL10n.deviceVerificationTitle
self.vc_removeBackTitle()
self.setupViews()
self.activityPresenter = ActivityIndicatorPresenter()
self.errorPresenter = MXKErrorAlertPresentation()
self.registerThemeServiceDidChangeThemeNotification()
self.update(theme: self.theme)
self.loadData()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return self.theme.statusBarStyle
}
// MARK: - Private
private func setupViews() {
}
private func update(theme: Theme) {
self.theme = theme
self.view.backgroundColor = theme.headerBackgroundColor
if let navigationBar = self.navigationController?.navigationBar {
theme.applyStyle(onNavigationBar: navigationBar)
}
}
private func registerThemeServiceDidChangeThemeNotification() {
NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange), name: .themeServiceDidChangeTheme, object: nil)
}
private func loadData() {
self.activityPresenter.presentActivityIndicator(on: self.view, animated: true)
if let otherUser = self.session.user(withUserId: otherUserId) {
self.session.crypto?.downloadKeys([self.otherUserId], forceDownload: false, success: { [weak self] (usersDevicesMap) in
guard let sself = self else {
return
}
sself.activityPresenter.removeCurrentActivityIndicator(animated: true)
if let otherDevice = usersDevicesMap?.object(forDevice: sself.otherDeviceId, forUser: sself.otherUserId) {
sself.delegate?.deviceVerificationDataLoadingViewControllerDidLoadData(sself, user: otherUser, device: otherDevice)
} else {
sself.errorPresenter.presentError(from: sself, title: "", message: VectorL10n.deviceVerificationErrorCannotLoadDevice, animated: true, handler: {
sself.delegate?.deviceVerificationDataLoadingViewControllerDidCancel(sself)
})
}
}, failure: { [weak self] (error) in
guard let sself = self else {
return
}
sself.activityPresenter.removeCurrentActivityIndicator(animated: true)
sself.errorPresenter.presentError(from: sself, forError: error, animated: true, handler: {
sself.delegate?.deviceVerificationDataLoadingViewControllerDidCancel(sself)
})
})
} else {
self.errorPresenter.presentError(from: self, title: "", message: VectorL10n.deviceVerificationErrorCannotLoadDevice, animated: true, handler: {
self.delegate?.deviceVerificationDataLoadingViewControllerDidCancel(self)
})
}
}
// MARK: - Actions
@objc private func themeDidChange() {
self.update(theme: ThemeService.shared().theme)
}
private func cancelButtonAction() {
self.delegate?.deviceVerificationDataLoadingViewControllerDidCancel(self)
}
}
@@ -65,6 +65,7 @@ final class DeviceVerificationStartViewController: UIViewController {
// Do any additional setup after loading the view.
self.title = VectorL10n.deviceVerificationTitle
self.vc_removeBackTitle()
self.setupViews()
self.keyboardAvoider = KeyboardAvoider(scrollViewContainerView: self.view, scrollView: self.scrollView)
@@ -64,6 +64,7 @@ final class DeviceVerificationVerifyViewController: UIViewController {
// Do any additional setup after loading the view.
self.title = VectorL10n.deviceVerificationTitle
self.vc_removeBackTitle()
self.setupViews()
self.keyboardAvoider = KeyboardAvoider(scrollViewContainerView: self.view, scrollView: self.scrollView)