Create self verification start screen.

This commit is contained in:
SBiOSoftWhare
2020-03-27 15:39:23 +01:00
parent 6710f58bfd
commit 06ffafcd93
12 changed files with 718 additions and 0 deletions
@@ -0,0 +1,71 @@
// File created from ScreenTemplate
// $ createScreen.sh KeyVerification KeyVerificationSelfVerifyStart
/*
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 KeyVerificationSelfVerifyStartCoordinator: KeyVerificationSelfVerifyStartCoordinatorType {
// MARK: - Properties
// MARK: Private
private let session: MXSession
private var keyVerificationSelfVerifyStartViewModel: KeyVerificationSelfVerifyStartViewModelType
private let keyVerificationSelfVerifyStartViewController: KeyVerificationSelfVerifyStartViewController
// MARK: Public
// Must be used only internally
var childCoordinators: [Coordinator] = []
weak var delegate: KeyVerificationSelfVerifyStartCoordinatorDelegate?
// MARK: - Setup
init(session: MXSession, otherDeviceId: String) {
self.session = session
let keyVerificationSelfVerifyStartViewModel = KeyVerificationSelfVerifyStartViewModel(session: self.session, otherDeviceId: otherDeviceId)
let keyVerificationSelfVerifyStartViewController = KeyVerificationSelfVerifyStartViewController.instantiate(with: keyVerificationSelfVerifyStartViewModel)
self.keyVerificationSelfVerifyStartViewModel = keyVerificationSelfVerifyStartViewModel
self.keyVerificationSelfVerifyStartViewController = keyVerificationSelfVerifyStartViewController
}
// MARK: - Public methods
func start() {
self.keyVerificationSelfVerifyStartViewModel.coordinatorDelegate = self
}
func toPresentable() -> UIViewController {
return self.keyVerificationSelfVerifyStartViewController
}
}
// MARK: - KeyVerificationSelfVerifyStartViewModelCoordinatorDelegate
extension KeyVerificationSelfVerifyStartCoordinator: KeyVerificationSelfVerifyStartViewModelCoordinatorDelegate {
func keyVerificationSelfVerifyStartViewModel(_ viewModel: KeyVerificationSelfVerifyStartViewModelType, otherDidAcceptRequest request: MXKeyVerificationRequest) {
self.delegate?.keyVerificationSelfVerifyStartCoordinator(self, otherDidAcceptRequest: request)
}
func keyVerificationSelfVerifyStartViewModelDidCancel(_ viewModel: KeyVerificationSelfVerifyStartViewModelType) {
self.delegate?.keyVerificationSelfVerifyStartCoordinatorDidCancel(self)
}
}
@@ -0,0 +1,31 @@
// File created from ScreenTemplate
// $ createScreen.sh KeyVerification KeyVerificationSelfVerifyStart
/*
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 KeyVerificationSelfVerifyStartCoordinatorDelegate: class {
func keyVerificationSelfVerifyStartCoordinator(_ coordinator: KeyVerificationSelfVerifyStartCoordinatorType, otherDidAcceptRequest request: MXKeyVerificationRequest)
func keyVerificationSelfVerifyStartCoordinatorDidCancel(_ coordinator: KeyVerificationSelfVerifyStartCoordinatorType)
}
/// `KeyVerificationSelfVerifyStartCoordinatorType` is a protocol describing a Coordinator that handle key backup setup passphrase navigation flow.
protocol KeyVerificationSelfVerifyStartCoordinatorType: Coordinator, Presentable {
var delegate: KeyVerificationSelfVerifyStartCoordinatorDelegate? { get }
}
@@ -0,0 +1,26 @@
// File created from ScreenTemplate
// $ createScreen.sh KeyVerification KeyVerificationSelfVerifyStart
/*
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
/// KeyVerificationSelfVerifyStartViewController view actions exposed to view model
enum KeyVerificationSelfVerifyStartViewAction {
case loadData
case startVerification
case cancel
}
@@ -0,0 +1,101 @@
<?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="KS5-Uc-kth">
<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>
<!--Key Verification Self Verify Start View Controller-->
<scene sceneID="QkI-t2-2u4">
<objects>
<viewController extendedLayoutIncludesOpaqueBars="YES" automaticallyAdjustsScrollViewInsets="NO" id="KS5-Uc-kth" customClass="KeyVerificationSelfVerifyStartViewController" customModule="Riot" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="aCd-C7-Sog">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="RcA-LK-bqZ">
<rect key="frame" x="0.0" y="254" width="375" height="179"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="For extra security, verify @user:matrix.org by checking a one-time code on both your devices." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ii0-Vq-vuo">
<rect key="frame" x="20" y="10" width="335" height="36"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Waiting for User…" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uxw-wa-UO3">
<rect key="frame" x="20" y="78" width="335" height="20.5"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1UA-CN-Osv">
<rect key="frame" x="20" y="66" width="335" height="44"/>
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCLoginButton"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="3X9-cq-oMn"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="kvu-Kt-I9J"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
<inset key="contentEdgeInsets" minX="30" minY="0.0" maxX="30" maxY="0.0"/>
<state key="normal" title="Start Verification">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="startVerificationButtonAction:" destination="KS5-Uc-kth" eventType="touchUpInside" id="XRr-SM-v5B"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="To be secure, do this in person or use another way to communicate." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9u5-8O-e7v">
<rect key="frame" x="20" y="130" width="335" height="29"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="1UA-CN-Osv" firstAttribute="width" secondItem="RcA-LK-bqZ" secondAttribute="width" priority="250" id="3op-EB-4AF"/>
<constraint firstItem="9u5-8O-e7v" firstAttribute="leading" secondItem="RcA-LK-bqZ" secondAttribute="leading" constant="20" id="61T-YH-HAT"/>
<constraint firstItem="uxw-wa-UO3" firstAttribute="leading" secondItem="RcA-LK-bqZ" secondAttribute="leading" constant="20" id="9re-dx-vNr"/>
<constraint firstAttribute="bottom" secondItem="9u5-8O-e7v" secondAttribute="bottom" constant="20" id="EfF-QJ-wlo"/>
<constraint firstItem="ii0-Vq-vuo" firstAttribute="leading" secondItem="RcA-LK-bqZ" secondAttribute="leading" constant="20" id="Gbr-0c-iNT"/>
<constraint firstAttribute="trailing" secondItem="uxw-wa-UO3" secondAttribute="trailing" constant="20" id="NLv-Oe-uKh"/>
<constraint firstItem="1UA-CN-Osv" firstAttribute="centerX" secondItem="RcA-LK-bqZ" secondAttribute="centerX" id="RfN-Zl-EQe"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="1UA-CN-Osv" secondAttribute="trailing" constant="20" id="Rpr-uL-hHS"/>
<constraint firstItem="uxw-wa-UO3" firstAttribute="centerY" secondItem="1UA-CN-Osv" secondAttribute="centerY" id="fqP-Kn-EeJ"/>
<constraint firstAttribute="trailing" secondItem="ii0-Vq-vuo" secondAttribute="trailing" constant="20" id="i1g-PR-xmm"/>
<constraint firstItem="1UA-CN-Osv" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="RcA-LK-bqZ" secondAttribute="leading" constant="20" id="jVa-iG-6nq"/>
<constraint firstItem="1UA-CN-Osv" firstAttribute="top" secondItem="ii0-Vq-vuo" secondAttribute="bottom" constant="20" id="tgh-3o-mbH"/>
<constraint firstAttribute="trailing" secondItem="9u5-8O-e7v" secondAttribute="trailing" constant="20" id="uif-YI-ctQ"/>
<constraint firstAttribute="height" priority="250" id="xC3-NI-fWd"/>
<constraint firstItem="ii0-Vq-vuo" firstAttribute="top" secondItem="RcA-LK-bqZ" secondAttribute="top" constant="10" id="yYJ-s1-biy"/>
<constraint firstItem="9u5-8O-e7v" firstAttribute="top" secondItem="1UA-CN-Osv" secondAttribute="bottom" constant="20" id="zB9-37-Afx"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="0.94509803920000002" green="0.96078431369999995" blue="0.97254901959999995" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstItem="RcA-LK-bqZ" firstAttribute="leading" secondItem="dcL-J3-zWj" secondAttribute="leading" id="6ju-83-vBd"/>
<constraint firstItem="RcA-LK-bqZ" firstAttribute="centerY" secondItem="dcL-J3-zWj" secondAttribute="centerY" id="PQc-Oc-xHj"/>
<constraint firstItem="RcA-LK-bqZ" firstAttribute="trailing" secondItem="dcL-J3-zWj" secondAttribute="trailing" id="Y9k-wq-avP"/>
</constraints>
<viewLayoutGuide key="safeArea" id="dcL-J3-zWj"/>
</view>
<connections>
<outlet property="additionalInformationLabel" destination="9u5-8O-e7v" id="yOX-2s-CJA"/>
<outlet property="informationLabel" destination="ii0-Vq-vuo" id="4bM-Ti-jbC"/>
<outlet property="startVerificationButton" destination="1UA-CN-Osv" id="PvC-Wh-KbN"/>
<outlet property="verificationWaitingLabel" destination="uxw-wa-UO3" id="R8a-Fa-txA"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="3s3-X3-VTR" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-3198" y="-647"/>
</scene>
</scenes>
</document>
@@ -0,0 +1,200 @@
// File created from ScreenTemplate
// $ createScreen.sh KeyVerification KeyVerificationSelfVerifyStart
/*
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 KeyVerificationSelfVerifyStartViewController: UIViewController {
// MARK: - Constants
private enum Constants {
static let verifyButtonCornerRadius: CGFloat = 8.0
}
// MARK: - Properties
// MARK: Outlets
@IBOutlet private weak var informationLabel: UILabel!
@IBOutlet private weak var startVerificationButton: UIButton!
@IBOutlet private weak var verificationWaitingLabel: UILabel!
@IBOutlet private weak var additionalInformationLabel: UILabel!
// MARK: Private
private var viewModel: KeyVerificationSelfVerifyStartViewModelType!
private var theme: Theme!
private var errorPresenter: MXKErrorPresentation!
private var activityPresenter: ActivityIndicatorPresenter!
// MARK: - Setup
class func instantiate(with viewModel: KeyVerificationSelfVerifyStartViewModelType) -> KeyVerificationSelfVerifyStartViewController {
let viewController = StoryboardScene.KeyVerificationSelfVerifyStartViewController.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.title = VectorL10n.deviceVerificationTitle
self.setupViews()
self.activityPresenter = ActivityIndicatorPresenter()
self.errorPresenter = MXKErrorAlertPresentation()
self.registerThemeServiceDidChangeThemeNotification()
self.update(theme: self.theme)
self.viewModel.viewDelegate = self
self.viewModel.process(viewAction: .loadData)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.startVerificationButton.layer.cornerRadius = Constants.verifyButtonCornerRadius
}
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)
}
self.informationLabel.textColor = theme.textPrimaryColor
self.startVerificationButton.vc_setBackgroundColor(theme.tintColor, for: .normal)
self.verificationWaitingLabel.textColor = theme.textSecondaryColor
self.additionalInformationLabel.textColor = theme.textSecondaryColor
}
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.startVerificationButton.layer.masksToBounds = true
self.startVerificationButton.setTitle(VectorL10n.deviceVerificationSelfVerifyStartVerifyAction, for: .normal)
self.verificationWaitingLabel.text = VectorL10n.deviceVerificationSelfVerifyStartWaiting
self.informationLabel.text = VectorL10n.deviceVerificationSelfVerifyStartInformation
self.additionalInformationLabel.text = nil
}
private func render(viewState: KeyVerificationSelfVerifyStartViewState) {
switch viewState {
case .loading:
self.renderLoading()
case .loaded:
self.renderLoaded()
case .error(let error):
self.render(error: error)
case .verificationPending:
self.renderVerificationPending()
case .cancelled(let reason):
self.renderCancelled(reason: reason)
case .cancelledByMe(let reason):
self.renderCancelledByMe(reason: reason)
}
}
private func renderLoading() {
self.activityPresenter.presentActivityIndicator(on: self.view, animated: true)
}
private func renderLoaded() {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
}
private func renderVerificationPending() {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
self.startVerificationButton.isHidden = true
self.verificationWaitingLabel.isHidden = false
}
private func render(error: Error) {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
self.errorPresenter.presentError(from: self, forError: error, animated: true, handler: nil)
}
private func renderCancelled(reason: MXTransactionCancelCode) {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
self.errorPresenter.presentError(from: self, title: "", message: VectorL10n.deviceVerificationCancelled, animated: true) {
self.viewModel.process(viewAction: .cancel)
}
}
private func renderCancelledByMe(reason: MXTransactionCancelCode) {
if reason.value != MXTransactionCancelCode.user().value {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
self.errorPresenter.presentError(from: self, title: "", message: VectorL10n.deviceVerificationCancelledByMe(reason.humanReadable), animated: true) {
self.viewModel.process(viewAction: .cancel)
}
} else {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
}
}
// MARK: - Actions
@IBAction private func startVerificationButtonAction(_ sender: Any) {
self.viewModel.process(viewAction: .startVerification)
}
private func cancelButtonAction() {
self.viewModel.process(viewAction: .cancel)
}
}
// MARK: - KeyVerificationSelfVerifyStartViewModelViewDelegate
extension KeyVerificationSelfVerifyStartViewController: KeyVerificationSelfVerifyStartViewModelViewDelegate {
func keyVerificationSelfVerifyStartViewModel(_ viewModel: KeyVerificationSelfVerifyStartViewModelType, didUpdateViewState viewSate: KeyVerificationSelfVerifyStartViewState) {
self.render(viewState: viewSate)
}
}
@@ -0,0 +1,144 @@
// File created from ScreenTemplate
// $ createScreen.sh KeyVerification KeyVerificationSelfVerifyStart
/*
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 KeyVerificationSelfVerifyStartViewModel: KeyVerificationSelfVerifyStartViewModelType {
// MARK: - Properties
// MARK: Private
private let session: MXSession
private let otherDeviceId: String
private let verificationManager: MXKeyVerificationManager
private let keyVerificationService: KeyVerificationService
private var keyVerificationRequest: MXKeyVerificationRequest?
// MARK: Public
weak var viewDelegate: KeyVerificationSelfVerifyStartViewModelViewDelegate?
weak var coordinatorDelegate: KeyVerificationSelfVerifyStartViewModelCoordinatorDelegate?
// MARK: - Setup
init(session: MXSession, otherDeviceId: String) {
self.session = session
self.verificationManager = session.crypto.keyVerificationManager
self.otherDeviceId = otherDeviceId
self.keyVerificationService = KeyVerificationService()
}
deinit {
}
// MARK: - Public
func process(viewAction: KeyVerificationSelfVerifyStartViewAction) {
switch viewAction {
case .loadData:
self.loadData()
case .startVerification:
self.startVerification()
case .cancel:
self.cancelKeyVerificationRequest()
self.coordinatorDelegate?.keyVerificationSelfVerifyStartViewModelDidCancel(self)
}
}
// MARK: - Private
private func loadData() {
self.startVerification()
}
private func startVerification() {
self.update(viewState: .verificationPending)
self.verificationManager.requestVerificationByToDevice(withUserId: session.myUser.userId, deviceIds: [otherDeviceId], methods: self.keyVerificationService.supportedKeyVerificationMethods(), success: { [weak self] (keyVerificationRequest) in
guard let self = self else {
return
}
self.keyVerificationRequest = keyVerificationRequest
self.update(viewState: .loaded)
self.registerKeyVerificationRequestDidChangeNotification(for: keyVerificationRequest)
}, failure: { [weak self] error in
self?.update(viewState: .error(error))
})
}
private func update(viewState: KeyVerificationSelfVerifyStartViewState) {
self.viewDelegate?.keyVerificationSelfVerifyStartViewModel(self, didUpdateViewState: viewState)
}
private func cancelKeyVerificationRequest() {
guard let keyVerificationRequest = self.keyVerificationRequest else {
return
}
keyVerificationRequest.cancel(with: MXTransactionCancelCode.user(), success: nil, failure: nil)
}
// MARK: - MXKeyVerificationRequestDidChange
private func registerKeyVerificationRequestDidChangeNotification(for keyVerificationRequest: MXKeyVerificationRequest) {
NotificationCenter.default.addObserver(self, selector: #selector(keyVerificationRequestDidChange(notification:)), name: .MXKeyVerificationRequestDidChange, object: keyVerificationRequest)
}
private func unregisterKeyVerificationRequestDidChangeNotification() {
NotificationCenter.default.removeObserver(self, name: .MXKeyVerificationRequestDidChange, object: nil)
}
@objc private func keyVerificationRequestDidChange(notification: Notification) {
guard let keyVerificationRequest = notification.object as? MXKeyVerificationRequest else {
return
}
guard let currentKeyVerificationRequest = self.keyVerificationRequest, keyVerificationRequest.requestId == currentKeyVerificationRequest.requestId else {
return
}
switch keyVerificationRequest.state {
case MXKeyVerificationRequestStateAccepted:
self.unregisterKeyVerificationRequestDidChangeNotification()
self.coordinatorDelegate?.keyVerificationSelfVerifyStartViewModel(self, otherDidAcceptRequest: currentKeyVerificationRequest)
case MXKeyVerificationRequestStateReady:
self.unregisterKeyVerificationRequestDidChangeNotification()
self.coordinatorDelegate?.keyVerificationSelfVerifyStartViewModel(self, otherDidAcceptRequest: currentKeyVerificationRequest)
case MXKeyVerificationRequestStateCancelled:
guard let reason = keyVerificationRequest.reasonCancelCode else {
return
}
self.unregisterKeyVerificationRequestDidChangeNotification()
self.update(viewState: .cancelled(reason))
case MXKeyVerificationRequestStateCancelledByMe:
guard let reason = keyVerificationRequest.reasonCancelCode else {
return
}
self.unregisterKeyVerificationRequestDidChangeNotification()
self.update(viewState: .cancelledByMe(reason))
case MXKeyVerificationRequestStateExpired:
self.unregisterKeyVerificationRequestDidChangeNotification()
self.update(viewState: .error(UserVerificationStartViewModelError.keyVerificationRequestExpired))
default:
break
}
}
}
@@ -0,0 +1,37 @@
// File created from ScreenTemplate
// $ createScreen.sh KeyVerification KeyVerificationSelfVerifyStart
/*
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 KeyVerificationSelfVerifyStartViewModelViewDelegate: class {
func keyVerificationSelfVerifyStartViewModel(_ viewModel: KeyVerificationSelfVerifyStartViewModelType, didUpdateViewState viewSate: KeyVerificationSelfVerifyStartViewState)
}
protocol KeyVerificationSelfVerifyStartViewModelCoordinatorDelegate: class {
func keyVerificationSelfVerifyStartViewModel(_ viewModel: KeyVerificationSelfVerifyStartViewModelType, otherDidAcceptRequest request: MXKeyVerificationRequest)
func keyVerificationSelfVerifyStartViewModelDidCancel(_ viewModel: KeyVerificationSelfVerifyStartViewModelType)
}
/// Protocol describing the view model used by `KeyVerificationSelfVerifyStartViewController`
protocol KeyVerificationSelfVerifyStartViewModelType {
var viewDelegate: KeyVerificationSelfVerifyStartViewModelViewDelegate? { get set }
var coordinatorDelegate: KeyVerificationSelfVerifyStartViewModelCoordinatorDelegate? { get set }
func process(viewAction: KeyVerificationSelfVerifyStartViewAction)
}
@@ -0,0 +1,29 @@
// File created from ScreenTemplate
// $ createScreen.sh KeyVerification KeyVerificationSelfVerifyStart
/*
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
/// KeyVerificationSelfVerifyStartViewController view state
enum KeyVerificationSelfVerifyStartViewState {
case loading
case loaded
case verificationPending
case cancelled(MXTransactionCancelCode)
case cancelledByMe(MXTransactionCancelCode)
case error(Error)
}