Refactoring secure backup references.

This commit is contained in:
SBiOSoftWhare
2020-06-26 13:07:53 +02:00
parent 808de8b15c
commit 17c5cdf06e
17 changed files with 205 additions and 142 deletions
@@ -1,101 +0,0 @@
/*
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
@objc protocol KeyBackupBannerCellDelegate: class {
func keyBackupBannerCellDidTapCloseAction(_ cell: KeyBackupBannerCell)
}
@objcMembers
final class KeyBackupBannerCell: MXKTableViewCell {
// MARK: - Properties
// MARK: Outlets
@IBOutlet private weak var shieldImageView: UIImageView!
@IBOutlet private weak var titleLabel: UILabel!
@IBOutlet private weak var subtitleLabel: UILabel!
@IBOutlet private weak var closeButton: UIButton!
// MARK: Public
weak var delegate: KeyBackupBannerCellDelegate?
// MARK: - Overrides
override class func defaultReuseIdentifier() -> String {
return String(describing: self)
}
override class func nib() -> UINib {
return UINib(nibName: String(describing: self), bundle: nil)
}
override func customizeRendering() {
super.customizeRendering()
let theme = ThemeService.shared().theme
self.shieldImageView.tintColor = theme.textPrimaryColor
self.closeButton.tintColor = theme.textPrimaryColor
self.titleLabel.textColor = theme.textPrimaryColor
self.subtitleLabel.textColor = theme.textPrimaryColor
}
// MARK: - Life cycle
override func awakeFromNib() {
super.awakeFromNib()
let shieldImage = Asset.Images.secretsSetupKey.image.withRenderingMode(.alwaysTemplate)
self.shieldImageView.image = shieldImage
let closeImage = Asset.Images.closeBanner.image.withRenderingMode(.alwaysTemplate)
self.closeButton.setImage(closeImage, for: .normal)
}
// MARK: - Public
func configure(for bannerDisplay: SecureBackupBannerDisplay) {
let title: String?
let subtitle: String?
switch bannerDisplay {
case .setup:
title = VectorL10n.secureBackupSetupBannerTitle
subtitle = VectorL10n.secureBackupSetupBannerSubtitle
case .recover:
title = VectorL10n.keyBackupRecoverBannerTitle
subtitle = VectorL10n.keyBackupRecoverConnentBannerSubtitle
default:
title = nil
subtitle = nil
}
self.titleLabel.text = title
self.subtitleLabel.text = subtitle
}
// MARK: - Actions
@IBAction private func closeButtonAction(_ sender: Any) {
self.delegate?.keyBackupBannerCellDidTapCloseAction(self)
}
}
@@ -1,84 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<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="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" rowHeight="81" id="KGk-i7-Jjw" customClass="KeyBackupBannerCell" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="651" height="81"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
<rect key="frame" x="0.0" y="0.0" width="651" height="80.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="secrets_setup_key" translatesAutoresizingMaskIntoConstraints="NO" id="9tN-7x-mQY">
<rect key="frame" x="20" y="24.5" width="32" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="32" id="34F-3o-CxQ"/>
<constraint firstAttribute="width" secondItem="9tN-7x-mQY" secondAttribute="height" multiplier="1:1" id="Anh-L2-mpZ"/>
</constraints>
</imageView>
<stackView opaque="NO" contentMode="scaleToFill" verticalCompressionResistancePriority="751" axis="vertical" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="YjT-XC-M1w">
<rect key="frame" x="77" y="15" width="512" height="50.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Secure Backup" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3Rt-ER-z7l">
<rect key="frame" x="0.0" y="0.0" width="512" height="24"/>
<fontDescription key="fontDescription" type="system" pointSize="20"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="Safeguard against losing access to encrypted messages &amp; data" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yvG-ND-8Ms">
<rect key="frame" x="0.0" y="26" width="512" height="24.5"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dfM-HD-aqv">
<rect key="frame" x="599" y="3" width="44" height="44"/>
<constraints>
<constraint firstAttribute="width" secondItem="dfM-HD-aqv" secondAttribute="height" multiplier="1:1" id="A8j-ze-vop"/>
<constraint firstAttribute="width" constant="44" id="sOg-81-aX8"/>
</constraints>
<state key="normal" image="close_banner"/>
<connections>
<action selector="closeButtonAction:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="JMQ-qw-PgK"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="YjT-XC-M1w" firstAttribute="top" secondItem="dfM-HD-aqv" secondAttribute="top" constant="12" id="4UB-Os-k5Z"/>
<constraint firstItem="YjT-XC-M1w" firstAttribute="leading" secondItem="9tN-7x-mQY" secondAttribute="trailing" constant="25" id="CaN-sn-hIV"/>
<constraint firstItem="9tN-7x-mQY" firstAttribute="top" relation="greaterThanOrEqual" secondItem="H2p-sc-9uM" secondAttribute="top" id="L5g-jO-DTI"/>
<constraint firstItem="9tN-7x-mQY" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="Nyv-QV-Pnf"/>
<constraint firstItem="9tN-7x-mQY" firstAttribute="centerY" secondItem="YjT-XC-M1w" secondAttribute="centerY" id="VaS-Jr-0Su"/>
<constraint firstItem="YjT-XC-M1w" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="15" id="Xz8-dz-WeL"/>
<constraint firstItem="dfM-HD-aqv" firstAttribute="leading" secondItem="YjT-XC-M1w" secondAttribute="trailing" constant="10" id="Zwn-hH-GnQ"/>
<constraint firstItem="9tN-7x-mQY" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="20" id="fmU-wC-fm5"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="9tN-7x-mQY" secondAttribute="bottom" id="gKz-je-baW"/>
<constraint firstAttribute="bottom" secondItem="YjT-XC-M1w" secondAttribute="bottom" constant="15" id="nub-27-ohD"/>
<constraint firstAttribute="trailing" secondItem="dfM-HD-aqv" secondAttribute="trailing" constant="8" id="xSp-FZ-mzB"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="closeButton" destination="dfM-HD-aqv" id="Yw7-ny-zfU"/>
<outlet property="shieldImageView" destination="9tN-7x-mQY" id="8sk-aT-hTz"/>
<outlet property="subtitleLabel" destination="yvG-ND-8Ms" id="Fvg-a0-Mx3"/>
<outlet property="titleLabel" destination="3Rt-ER-z7l" id="pLB-4l-jTK"/>
</connections>
<point key="canvasLocation" x="-1503.2" y="-521.28935532233891"/>
</tableViewCell>
</objects>
<resources>
<image name="close_banner" width="10" height="10"/>
<image name="secrets_setup_key" width="48" height="48"/>
</resources>
</document>
@@ -1,77 +0,0 @@
/*
Copyright 2018 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
/// Key backup banner user preferences.
@objcMembers
final class KeyBackupBannerPreferences: NSObject {
// MARK: - Constants
private enum UserDefaultsKeys {
static let hideSetupBanner = "KeyBackupBannerPreferencesHideSetupBanner"
static let hiddenRecoverBannerKeyBackupVersions = "KeyBackupBannerPreferencesHiddenRecoverBannerKeyBackupVersions"
}
static let shared = KeyBackupBannerPreferences()
// MARK: - Properties
private var hiddenRecoverBannerKeyBackupVersions: [String] {
get {
return UserDefaults.standard.stringArray(forKey: UserDefaultsKeys.hiddenRecoverBannerKeyBackupVersions) ?? []
}
set {
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.hiddenRecoverBannerKeyBackupVersions)
}
}
// MARK: - Public
/// Remember to hide key backup setup banner.
var hideSetupBanner: Bool {
get {
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.hideSetupBanner)
}
set {
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.hideSetupBanner)
}
}
/// Remember to hide key backup recover banner for specific key backup version.
///
/// - Parameter keyBackupVersion: Key backup version recover banner to hide.
func hideRecoverBanner(for keyBackupVersion: String) {
guard self.hiddenRecoverBannerKeyBackupVersions.contains(keyBackupVersion) == false else {
return
}
self.hiddenRecoverBannerKeyBackupVersions.append(keyBackupVersion)
}
/// Check if key backup recover banner should be hidden for key backup version.
///
/// - Parameter keyBackupVersion: Key backup version to check.
/// - Returns: true if recover banner should be hidden.
func isRecoverBannerHidden(for keyBackupVersion: String) -> Bool {
return self.hiddenRecoverBannerKeyBackupVersions.contains(keyBackupVersion)
}
/// Reset key backup banner preferences to default values
func reset() {
self.hideSetupBanner = false
self.hiddenRecoverBannerKeyBackupVersions = []
}
}
@@ -1,157 +0,0 @@
/*
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
import Reusable
final class SecureKeyBackupSetupIntroCell: UIView, NibOwnerLoadable, Themable {
// MARK: - Constants
private enum ImageAlpha {
static let highlighted: CGFloat = 0.3
}
// MARK: - Properties
// MARK: Outlets
@IBOutlet private weak var backgroundView: UIView!
@IBOutlet private weak var imageView: UIImageView!
@IBOutlet private weak var titleLabel: UILabel!
@IBOutlet private weak var informationLabel: UILabel!
@IBOutlet private weak var accessoryImageView: UIImageView!
@IBOutlet private weak var separatorView: UIView!
// MARK: Private
private var theme: Theme?
private var isHighlighted: Bool = false {
didSet {
self.updateView()
}
}
// MARK: Public
var action: (() -> Void)?
// MARK: Setup
private func commonInit() {
self.setupGestureRecognizer()
let accessoryTemplateImage = Asset.Images.disclosureIcon.image.withRenderingMode(.alwaysTemplate)
self.accessoryImageView.image = accessoryTemplateImage
self.accessoryImageView.highlightedImage = accessoryTemplateImage.vc_withAlpha(ImageAlpha.highlighted)
}
convenience init() {
self.init(frame: CGRect.zero)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.loadNibContent()
self.commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.loadNibContent()
self.commonInit()
}
// MARK: - Public
func update(theme: Theme) {
self.theme = theme
self.backgroundView.backgroundColor = theme.backgroundColor
self.imageView.tintColor = theme.textPrimaryColor
self.titleLabel.textColor = theme.tintColor
self.informationLabel.textColor = theme.textSecondaryColor
self.accessoryImageView.tintColor = theme.textSecondaryColor
self.separatorView.backgroundColor = theme.lineBreakColor
self.updateView()
}
func fill(title: String, information: String, image: UIImage) {
let templateImage = image.withRenderingMode(.alwaysTemplate)
self.imageView.image = templateImage
self.imageView.highlightedImage = templateImage.vc_withAlpha(ImageAlpha.highlighted)
self.titleLabel.text = title
self.informationLabel.text = information
self.setupAccessibility(title: title, isEnabled: true)
self.updateView()
}
// MARK: - Private
private func setupAccessibility(title: String, isEnabled: Bool) {
self.isAccessibilityElement = true
self.accessibilityLabel = title
self.accessibilityTraits = .button
if !isEnabled {
self.accessibilityTraits.insert(.notEnabled)
}
}
private func setupGestureRecognizer() {
let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(buttonAction(_:)))
gestureRecognizer.minimumPressDuration = 0
self.addGestureRecognizer(gestureRecognizer)
}
private func updateView() {
if let theme = self.theme {
self.backgroundView.backgroundColor = self.isHighlighted ? theme.overlayBackgroundColor : theme.backgroundColor
}
self.imageView.isHighlighted = self.isHighlighted
self.accessoryImageView.isHighlighted = self.isHighlighted
}
// MARK: - Actions
@objc private func buttonAction(_ sender: UILongPressGestureRecognizer) {
let isBackgroundViewTouched = sender.vc_isTouchingInside()
switch sender.state {
case .began, .changed:
self.isHighlighted = isBackgroundViewTouched
case .ended:
self.isHighlighted = false
if isBackgroundViewTouched {
self.action?()
}
case .cancelled:
self.isHighlighted = false
default:
break
}
}
}
@@ -1,102 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<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>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SecureKeyBackupSetupIntroCell" customModule="Riot" customModuleProvider="target">
<connections>
<outlet property="accessoryImageView" destination="N76-Fa-onz" id="nYX-r6-t7R"/>
<outlet property="backgroundView" destination="WrK-Wq-nzz" id="kgB-Zb-g9N"/>
<outlet property="imageView" destination="PfY-xb-Psn" id="qgq-7B-nSS"/>
<outlet property="informationLabel" destination="q9X-wE-MwV" id="a4J-ZK-teU"/>
<outlet property="separatorView" destination="eKS-Ze-zhB" id="TF5-27-XFD"/>
<outlet property="titleLabel" destination="eGd-jn-myj" id="MyG-x1-33i"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="426" height="122"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="WrK-Wq-nzz">
<rect key="frame" x="0.0" y="0.0" width="426" height="122"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="secrets_setup_key" translatesAutoresizingMaskIntoConstraints="NO" id="PfY-xb-Psn">
<rect key="frame" x="19" y="18" width="24" height="24"/>
<constraints>
<constraint firstAttribute="width" secondItem="PfY-xb-Psn" secondAttribute="height" multiplier="1:1" id="71S-sH-VTt"/>
<constraint firstAttribute="width" constant="24" id="Shz-Df-UoM"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="252" text="Use a Security Key" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eGd-jn-myj">
<rect key="frame" x="63" y="20" width="317" height="19.5"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="0.01176470588" green="0.70196078429999997" blue="0.50588235290000005" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Generate a security key to store somewhere safe like a password manager or a safe." lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="q9X-wE-MwV">
<rect key="frame" x="63" y="49.5" width="317" height="52.5"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="disclosure_icon" translatesAutoresizingMaskIntoConstraints="NO" id="N76-Fa-onz">
<rect key="frame" x="400" y="55" width="6" height="12"/>
<constraints>
<constraint firstAttribute="width" constant="6" id="23d-HN-WiD"/>
<constraint firstAttribute="height" constant="12" id="4Yt-I6-2YL"/>
</constraints>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eKS-Ze-zhB" userLabel="separatorView">
<rect key="frame" x="0.0" y="121" width="426" height="1"/>
<color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="5hw-tO-Dw9"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="PfY-xb-Psn" firstAttribute="centerY" secondItem="eGd-jn-myj" secondAttribute="centerY" id="3Ha-I2-24v"/>
<constraint firstAttribute="trailing" secondItem="N76-Fa-onz" secondAttribute="trailing" constant="20" id="9C0-mv-gaL"/>
<constraint firstAttribute="trailing" secondItem="eKS-Ze-zhB" secondAttribute="trailing" id="BlW-zS-HoC"/>
<constraint firstItem="N76-Fa-onz" firstAttribute="leading" secondItem="eGd-jn-myj" secondAttribute="trailing" constant="20" id="CKw-l3-vdY"/>
<constraint firstItem="PfY-xb-Psn" firstAttribute="leading" secondItem="WrK-Wq-nzz" secondAttribute="leading" constant="19" id="NXM-42-myZ"/>
<constraint firstItem="q9X-wE-MwV" firstAttribute="leading" secondItem="eGd-jn-myj" secondAttribute="leading" id="Ovd-Xd-S7O"/>
<constraint firstAttribute="bottom" secondItem="q9X-wE-MwV" secondAttribute="bottom" constant="20" id="S9M-i1-KQ6"/>
<constraint firstItem="q9X-wE-MwV" firstAttribute="trailing" secondItem="eGd-jn-myj" secondAttribute="trailing" id="YU0-XX-vAU"/>
<constraint firstItem="eGd-jn-myj" firstAttribute="top" secondItem="WrK-Wq-nzz" secondAttribute="top" constant="20" id="cAQ-R0-bco"/>
<constraint firstAttribute="bottom" secondItem="eKS-Ze-zhB" secondAttribute="bottom" id="cnI-2n-T2c"/>
<constraint firstItem="q9X-wE-MwV" firstAttribute="top" secondItem="eGd-jn-myj" secondAttribute="bottom" constant="10" id="kYI-mK-UC1"/>
<constraint firstItem="N76-Fa-onz" firstAttribute="centerY" secondItem="WrK-Wq-nzz" secondAttribute="centerY" id="rG1-iI-v3T"/>
<constraint firstItem="eKS-Ze-zhB" firstAttribute="leading" secondItem="WrK-Wq-nzz" secondAttribute="leading" id="raL-7N-TKN"/>
<constraint firstItem="eGd-jn-myj" firstAttribute="leading" secondItem="PfY-xb-Psn" secondAttribute="trailing" constant="20" id="zi9-PT-A2O"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="WrK-Wq-nzz" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="dAF-lS-uGD"/>
<constraint firstItem="WrK-Wq-nzz" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="fAW-fz-tYP"/>
<constraint firstAttribute="bottom" secondItem="WrK-Wq-nzz" secondAttribute="bottom" id="lU3-Jc-aUe"/>
<constraint firstAttribute="trailing" secondItem="WrK-Wq-nzz" secondAttribute="trailing" id="lUt-K8-wV9"/>
</constraints>
<nil key="simulatedTopBarMetrics"/>
<nil key="simulatedBottomBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<point key="canvasLocation" x="146.37681159420291" y="-122.54464285714285"/>
</view>
</objects>
<resources>
<image name="disclosure_icon" width="6" height="12"/>
<image name="secrets_setup_key" width="48" height="48"/>
</resources>
</document>
@@ -1,132 +0,0 @@
<?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="LSX-Vb-DIu">
<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>
<!--Secure Key Backup Setup Intro View Controller-->
<scene sceneID="srP-wo-sRp">
<objects>
<viewController extendedLayoutIncludesOpaqueBars="YES" automaticallyAdjustsScrollViewInsets="NO" id="LSX-Vb-DIu" customClass="SecureKeyBackupSetupIntroViewController" customModule="Riot" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="pmD-eJ-G3m">
<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="mvC-lc-ylT">
<rect key="frame" x="0.0" y="44" width="414" height="852"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Fub-g4-o4o">
<rect key="frame" x="0.0" y="0.0" width="414" height="391"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="79w-lw-B8z">
<rect key="frame" x="0.0" y="0.0" width="414" height="391"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Safe guard against losing access to encrypted messages &amp; data by backing up encryption keys on your server." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DZf-di-JcI">
<rect key="frame" x="20" y="30" width="374" height="54"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tul-b1-7gY">
<rect key="frame" x="0.0" y="114" width="414" height="257"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="Jc9-fc-Vwh">
<rect key="frame" x="0.0" y="0.0" width="414" height="257"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="d77-sQ-Uio">
<rect key="frame" x="0.0" y="0.0" width="414" height="1"/>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="Gwq-JQ-4Zj"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="RQF-pm-g37" customClass="SecureKeyBackupSetupIntroCell" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="0.0" y="1" width="414" height="128"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="128" placeholder="YES" id="dOF-Du-P3S"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Yps-bc-ruH" customClass="SecureKeyBackupSetupIntroCell" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="0.0" y="129" width="414" height="128"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="128" placeholder="YES" id="Gpk-nd-3G2"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstItem="d77-sQ-Uio" firstAttribute="width" secondItem="Jc9-fc-Vwh" secondAttribute="width" id="S3Q-F0-nwW"/>
<constraint firstItem="RQF-pm-g37" firstAttribute="width" secondItem="Jc9-fc-Vwh" secondAttribute="width" id="fZs-9s-jUW"/>
</constraints>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="Jc9-fc-Vwh" firstAttribute="top" secondItem="tul-b1-7gY" secondAttribute="top" id="1Vr-Y3-t2r"/>
<constraint firstItem="Jc9-fc-Vwh" firstAttribute="leading" secondItem="tul-b1-7gY" secondAttribute="leading" id="4op-QY-3vL"/>
<constraint firstAttribute="bottom" secondItem="Jc9-fc-Vwh" secondAttribute="bottom" id="FqW-Rc-K1T"/>
<constraint firstAttribute="trailing" secondItem="Jc9-fc-Vwh" secondAttribute="trailing" id="QcB-wY-lCT"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="tul-b1-7gY" secondAttribute="trailing" id="TFD-iw-7y4"/>
<constraint firstItem="tul-b1-7gY" firstAttribute="top" secondItem="DZf-di-JcI" secondAttribute="bottom" constant="30" id="Ury-rf-0xS"/>
<constraint firstAttribute="trailing" secondItem="DZf-di-JcI" secondAttribute="trailing" constant="20" id="bS3-Gc-DyD"/>
<constraint firstAttribute="width" priority="750" constant="500" id="fuc-5G-HCd"/>
<constraint firstItem="tul-b1-7gY" firstAttribute="leading" secondItem="79w-lw-B8z" secondAttribute="leading" id="gYj-LZ-esB"/>
<constraint firstItem="DZf-di-JcI" firstAttribute="leading" secondItem="79w-lw-B8z" secondAttribute="leading" constant="20" id="nPo-3g-WcD"/>
<constraint firstAttribute="bottom" secondItem="tul-b1-7gY" secondAttribute="bottom" constant="20" id="qYa-0L-wrp"/>
<constraint firstItem="DZf-di-JcI" firstAttribute="top" secondItem="79w-lw-B8z" secondAttribute="top" constant="30" id="t80-aS-JzH"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="79w-lw-B8z" firstAttribute="centerX" secondItem="Fub-g4-o4o" secondAttribute="centerX" id="5Az-52-cbQ"/>
<constraint firstItem="79w-lw-B8z" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Fub-g4-o4o" secondAttribute="leading" id="Aei-Nr-Wzb"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="79w-lw-B8z" secondAttribute="trailing" id="CBG-M0-Uqd"/>
<constraint firstAttribute="bottom" secondItem="79w-lw-B8z" secondAttribute="bottom" id="JbI-yr-iot"/>
<constraint firstItem="79w-lw-B8z" firstAttribute="top" secondItem="Fub-g4-o4o" secondAttribute="top" id="s6B-HO-iVd"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="Fub-g4-o4o" secondAttribute="trailing" id="N9B-1U-3j7"/>
<constraint firstItem="Fub-g4-o4o" firstAttribute="width" secondItem="mvC-lc-ylT" secondAttribute="width" id="NzH-5s-nuz"/>
<constraint firstAttribute="bottom" secondItem="Fub-g4-o4o" secondAttribute="bottom" id="gYj-V0-rlA"/>
<constraint firstItem="Fub-g4-o4o" firstAttribute="leading" secondItem="mvC-lc-ylT" secondAttribute="leading" id="jHU-W6-8Ny"/>
<constraint firstItem="Fub-g4-o4o" firstAttribute="top" secondItem="mvC-lc-ylT" secondAttribute="top" id="nFB-Af-IUw"/>
</constraints>
</scrollView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="JkH-9M-Qql" firstAttribute="top" secondItem="mvC-lc-ylT" secondAttribute="top" id="5Vc-aR-jAF"/>
<constraint firstItem="mvC-lc-ylT" firstAttribute="leading" secondItem="JkH-9M-Qql" secondAttribute="leading" id="HBB-YL-5P5"/>
<constraint firstAttribute="bottom" secondItem="mvC-lc-ylT" secondAttribute="bottom" id="dn5-CG-87P"/>
<constraint firstItem="JkH-9M-Qql" firstAttribute="trailing" secondItem="mvC-lc-ylT" secondAttribute="trailing" id="xj4-xF-VEA"/>
</constraints>
<viewLayoutGuide key="safeArea" id="JkH-9M-Qql"/>
</view>
<connections>
<outlet property="informationLabel" destination="DZf-di-JcI" id="czR-MT-Ipb"/>
<outlet property="secureKeyCell" destination="RQF-pm-g37" id="5dK-h1-N6t"/>
<outlet property="securePassphraseCell" destination="Yps-bc-ruH" id="56B-9H-MOh"/>
<outlet property="topSeparatorView" destination="d77-sQ-Uio" id="TPp-kq-cFq"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="WpU-UP-qtu" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-3772.4637681159425" y="-774.10714285714278"/>
</scene>
</scenes>
</document>
@@ -1,133 +0,0 @@
/*
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
protocol SecureKeyBackupSetupIntroViewControllerDelegate: class {
func secureKeyBackupSetupIntroViewControllerDidTapUseKey(_ secureKeyBackupSetupIntroViewController: SecureKeyBackupSetupIntroViewController)
func secureKeyBackupSetupIntroViewControllerDidTapUsePassphrase(_ secureKeyBackupSetupIntroViewController: SecureKeyBackupSetupIntroViewController)
func secureKeyBackupSetupIntroViewControllerDidCancel(_ secureKeyBackupSetupIntroViewController: SecureKeyBackupSetupIntroViewController)
}
@objcMembers
final class SecureKeyBackupSetupIntroViewController: UIViewController {
// MARK: - Properties
// MARK: Outlets
@IBOutlet private weak var informationLabel: UILabel!
@IBOutlet private weak var topSeparatorView: UIView!
@IBOutlet private weak var secureKeyCell: SecureKeyBackupSetupIntroCell!
@IBOutlet private weak var securePassphraseCell: SecureKeyBackupSetupIntroCell!
// MARK: Private
private var theme: Theme!
// MARK: Public
weak var delegate: SecureKeyBackupSetupIntroViewControllerDelegate?
// MARK: - Setup
class func instantiate() -> SecureKeyBackupSetupIntroViewController {
let viewController = StoryboardScene.SecureKeyBackupSetupIntroViewController.initialScene.instantiate()
viewController.theme = ThemeService.shared().theme
return viewController
}
// MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.vc_removeBackTitle()
self.setupViews()
self.registerThemeServiceDidChangeThemeNotification()
self.update(theme: self.theme)
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return self.theme.statusBarStyle
}
// MARK: - Private
private func setupViews() {
let cancelBarButtonItem = MXKBarButtonItem(title: VectorL10n.cancel, style: .plain) { [weak self] in
guard let self = self else {
return
}
self.delegate?.secureKeyBackupSetupIntroViewControllerDidCancel(self)
}
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
self.title = VectorL10n.secureKeyBackupSetupIntroTitle
self.informationLabel.text = VectorL10n.secureKeyBackupSetupIntroInfo
self.secureKeyCell.fill(title: VectorL10n.secureKeyBackupSetupIntroUseSecurityKeyTitle,
information: VectorL10n.secureKeyBackupSetupIntroUseSecurityKeyInfo,
image: Asset.Images.secretsSetupKey.image)
self.secureKeyCell.action = { [weak self] in
guard let self = self else {
return
}
self.delegate?.secureKeyBackupSetupIntroViewControllerDidTapUseKey(self)
}
self.securePassphraseCell.fill(title: VectorL10n.secureKeyBackupSetupIntroUseSecurityPassphraseTitle,
information: VectorL10n.secureKeyBackupSetupIntroUseSecurityPassphraseInfo,
image: Asset.Images.secretsSetupPassphrase.image)
self.securePassphraseCell.action = { [weak self] in
guard let self = self else {
return
}
self.delegate?.secureKeyBackupSetupIntroViewControllerDidTapUsePassphrase(self)
}
}
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.topSeparatorView.backgroundColor = theme.lineBreakColor
self.secureKeyCell.update(theme: theme)
self.securePassphraseCell.update(theme: theme)
}
private func registerThemeServiceDidChangeThemeNotification() {
NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange), name: .themeServiceDidChangeTheme, object: nil)
}
@objc private func themeDidChange() {
self.update(theme: ThemeService.shared().theme)
}
}
@@ -1,171 +0,0 @@
// File created from FlowTemplate
// $ createRootCoordinator.sh KeyBackupSetup/SecureSetup SecureKeyBackupSetup
/*
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 SecureKeyBackupSetupCoordinator: SecureKeyBackupSetupCoordinatorType {
// MARK: - Properties
// MARK: Private
private let navigationRouter: NavigationRouterType
private let recoveryService: MXRecoveryService
// MARK: Public
// Must be used only internally
var childCoordinators: [Coordinator] = []
weak var delegate: SecureKeyBackupSetupCoordinatorDelegate?
// MARK: - Setup
init(session: MXSession) {
self.navigationRouter = NavigationRouter(navigationController: RiotNavigationController())
self.recoveryService = session.crypto.recoveryService
}
// MARK: - Public methods
func start() {
let rootViewController = self.createIntro()
self.navigationRouter.setRootModule(rootViewController)
}
func toPresentable() -> UIViewController {
return self.navigationRouter.toPresentable()
}
// MARK: - Private methods
private func createIntro() -> SecureKeyBackupSetupIntroViewController {
let introViewController = SecureKeyBackupSetupIntroViewController.instantiate()
introViewController.delegate = self
return introViewController
}
private func showSetupKey(passphrase: String? = nil) {
let coordinator = SecretsSetupRecoveryKeyCoordinator(recoveryService: self.recoveryService, passphrase: passphrase)
coordinator.delegate = self
coordinator.start()
self.add(childCoordinator: coordinator)
self.navigationRouter.push(coordinator, animated: true) { [weak self] in
self?.remove(childCoordinator: coordinator)
}
}
private func showSetupPassphrase() {
let coordinator = SecretsSetupRecoveryPassphraseCoordinator(passphraseInput: .new)
coordinator.delegate = self
coordinator.start()
self.add(childCoordinator: coordinator)
self.navigationRouter.push(coordinator, animated: true) { [weak self] in
self?.remove(childCoordinator: coordinator)
}
}
private func showSetupPassphraseConfirmation(with passphrase: String) {
let coordinator = SecretsSetupRecoveryPassphraseCoordinator(passphraseInput: .confirm(passphrase))
coordinator.delegate = self
coordinator.start()
self.add(childCoordinator: coordinator)
self.navigationRouter.push(coordinator, animated: true) { [weak self] in
self?.remove(childCoordinator: coordinator)
}
}
private func showCancelAlert() {
let alertController = UIAlertController(title: VectorL10n.secureKeyBackupSetupCancelAlertTitle,
message: VectorL10n.secureKeyBackupSetupCancelAlertMessage,
preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: VectorL10n.continue, style: .cancel, handler: { action in
}))
alertController.addAction(UIAlertAction(title: VectorL10n.keyBackupSetupSkipAlertSkipAction, style: .default, handler: { action in
self.delegate?.secureKeyBackupSetupCoordinatorDidCancel(self)
}))
self.navigationRouter.present(alertController, animated: true)
}
private func didCancel(showSkipAlert: Bool = true) {
if showSkipAlert {
self.showCancelAlert()
} else {
self.delegate?.secureKeyBackupSetupCoordinatorDidCancel(self)
}
}
private func didComplete() {
self.delegate?.secureKeyBackupSetupCoordinatorDidComplete(self)
}
}
// MARK: - SecureKeyBackupSetupIntroViewControllerDelegate
extension SecureKeyBackupSetupCoordinator: SecureKeyBackupSetupIntroViewControllerDelegate {
func secureKeyBackupSetupIntroViewControllerDidTapUseKey(_ secureKeyBackupSetupIntroViewController: SecureKeyBackupSetupIntroViewController) {
self.showSetupKey()
}
func secureKeyBackupSetupIntroViewControllerDidTapUsePassphrase(_ secureKeyBackupSetupIntroViewController: SecureKeyBackupSetupIntroViewController) {
self.showSetupPassphrase()
}
func secureKeyBackupSetupIntroViewControllerDidCancel(_ secureKeyBackupSetupIntroViewController: SecureKeyBackupSetupIntroViewController) {
self.didCancel()
}
}
// MARK: - SecretsSetupRecoveryKeyCoordinatorDelegate
extension SecureKeyBackupSetupCoordinator: SecretsSetupRecoveryKeyCoordinatorDelegate {
func secretsSetupRecoveryKeyCoordinatorDidComplete(_ coordinator: SecretsSetupRecoveryKeyCoordinatorType) {
self.didComplete()
}
func secretsSetupRecoveryKeyCoordinatorDidFailed(_ coordinator: SecretsSetupRecoveryKeyCoordinatorType) {
self.didCancel(showSkipAlert: false)
}
func secretsSetupRecoveryKeyCoordinatorDidCancel(_ coordinator: SecretsSetupRecoveryKeyCoordinatorType) {
self.didCancel()
}
}
// MARK: - SecretsSetupRecoveryPassphraseCoordinatorDelegate
extension SecureKeyBackupSetupCoordinator: SecretsSetupRecoveryPassphraseCoordinatorDelegate {
func secretsSetupRecoveryPassphraseCoordinator(_ coordinator: SecretsSetupRecoveryPassphraseCoordinatorType, didEnterNewPassphrase passphrase: String) {
self.showSetupPassphraseConfirmation(with: passphrase)
}
func secretsSetupRecoveryPassphraseCoordinator(_ coordinator: SecretsSetupRecoveryPassphraseCoordinatorType, didConfirmPassphrase passphrase: String) {
self.showSetupKey(passphrase: passphrase)
}
func secretsSetupRecoveryPassphraseCoordinatorDidCancel(_ coordinator: SecretsSetupRecoveryPassphraseCoordinatorType) {
self.didCancel()
}
}
@@ -1,88 +0,0 @@
// File created from FlowTemplate
// $ createRootCoordinator.sh KeyBackupSetup/SecureSetup SecureKeyBackupSetup
/*
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 SecureKeyBackupSetupCoordinatorBridgePresenterDelegate {
func secureKeyBackupSetupCoordinatorBridgePresenterDelegateDidComplete(_ coordinatorBridgePresenter: SecureKeyBackupSetupCoordinatorBridgePresenter)
func secureKeyBackupSetupCoordinatorBridgePresenterDelegateDidCancel(_ coordinatorBridgePresenter: SecureKeyBackupSetupCoordinatorBridgePresenter)
}
/// SecureKeyBackupSetupCoordinatorBridgePresenter enables to start SecureKeyBackupSetupCoordinator from a view controller.
/// This bridge is used while waiting for global usage of coordinator pattern.
@objcMembers
final class SecureKeyBackupSetupCoordinatorBridgePresenter: NSObject {
// MARK: - Properties
// MARK: Private
private let session: MXSession
private var coordinator: SecureKeyBackupSetupCoordinator?
// MARK: Public
weak var delegate: SecureKeyBackupSetupCoordinatorBridgePresenterDelegate?
// 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 secureKeyBackupSetupCoordinator = SecureKeyBackupSetupCoordinator(session: self.session)
secureKeyBackupSetupCoordinator.delegate = self
viewController.present(secureKeyBackupSetupCoordinator.toPresentable(), animated: animated, completion: nil)
secureKeyBackupSetupCoordinator.start()
self.coordinator = secureKeyBackupSetupCoordinator
}
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: - SecureKeyBackupSetupCoordinatorDelegate
extension SecureKeyBackupSetupCoordinatorBridgePresenter: SecureKeyBackupSetupCoordinatorDelegate {
func secureKeyBackupSetupCoordinatorDidComplete(_ coordinator: SecureKeyBackupSetupCoordinatorType) {
self.delegate?.secureKeyBackupSetupCoordinatorBridgePresenterDelegateDidComplete(self)
}
func secureKeyBackupSetupCoordinatorDidCancel(_ coordinator: SecureKeyBackupSetupCoordinatorType) {
self.delegate?.secureKeyBackupSetupCoordinatorBridgePresenterDelegateDidCancel(self)
}
}
@@ -1,29 +0,0 @@
// File created from FlowTemplate
// $ createRootCoordinator.sh KeyBackupSetup/SecureSetup SecureKeyBackupSetup
/*
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 SecureKeyBackupSetupCoordinatorDelegate: class {
func secureKeyBackupSetupCoordinatorDidComplete(_ coordinator: SecureKeyBackupSetupCoordinatorType)
func secureKeyBackupSetupCoordinatorDidCancel(_ coordinator: SecureKeyBackupSetupCoordinatorType)
}
/// `SecureKeyBackupSetupCoordinatorType` is a protocol describing a Coordinator that handle keybackup setup navigation flow.
protocol SecureKeyBackupSetupCoordinatorType: Coordinator, Presentable {
var delegate: SecureKeyBackupSetupCoordinatorDelegate? { get }
}