diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2021-03-18 09:52:25 +0100 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2021-03-22 16:36:14 +0100 |
| commit | 807d3bd61161bccbc73ef15636274aefbd006916 (patch) | |
| tree | 27469bd9f59cae88d793d42fb3debcd5929e0809 | |
| parent | 4facd7e9fa1eeddfd716a342e2c248f1ed32c672 (diff) | |
| download | mullvadvpn-807d3bd61161bccbc73ef15636274aefbd006916.tar.xz mullvadvpn-807d3bd61161bccbc73ef15636274aefbd006916.zip | |
Extract the main content view into a separate class
| -rw-r--r-- | ios/MullvadVPN.xcodeproj/project.pbxproj | 8 | ||||
| -rw-r--r-- | ios/MullvadVPN/ConnectMainContentView.swift | 147 | ||||
| -rw-r--r-- | ios/MullvadVPN/ConnectViewController.swift | 143 | ||||
| -rw-r--r-- | ios/MullvadVPN/ConnectViewController.xib | 113 |
4 files changed, 222 insertions, 189 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj index 9e5371459d..394992b99b 100644 --- a/ios/MullvadVPN.xcodeproj/project.pbxproj +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -154,6 +154,7 @@ 58B0A2AC238EE6D500BC001D /* IPAddress+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5840250022B1124600E4CFEC /* IPAddress+Codable.swift */; }; 58B0A2AD238EE6EC00BC001D /* MullvadEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5840250322B11AB700E4CFEC /* MullvadEndpoint.swift */; }; 58B67B482602079E008EF58E /* RelaySelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58781CD422AFBA39009B9D8E /* RelaySelector.swift */; }; + 58B43C1925F77DB60002C8C3 /* ConnectMainContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58B43C1825F77DB60002C8C3 /* ConnectMainContentView.swift */; }; 58B8743222B25A7600015324 /* WireguardAssociatedAddresses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58B8743122B25A7600015324 /* WireguardAssociatedAddresses.swift */; }; 58B8743B22B788D200015324 /* PacketTunnelSettingsGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58B8743722B25EAB00015324 /* PacketTunnelSettingsGenerator.swift */; }; 58B9814E24FEA70D00C0D59E /* WireguardKeysViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 58B9814D24FEA70D00C0D59E /* WireguardKeysViewController.xib */; }; @@ -193,7 +194,6 @@ 58CE5E81224146470008646E /* PacketTunnel.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 58CE5E79224146470008646E /* PacketTunnel.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 58D0C79E23F1CEBA00FE9BA7 /* SnapshotHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58D0C79D23F1CEBA00FE9BA7 /* SnapshotHelper.swift */; }; 58D0C7A223F1CECF00FE9BA7 /* MullvadVPNScreenshots.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58D0C7A023F1CECF00FE9BA7 /* MullvadVPNScreenshots.swift */; }; - 58D9AF6B2501111800B6FAB5 /* ConnectViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 58D9AF6A2501111800B6FAB5 /* ConnectViewController.xib */; }; 58DF28A52417CB4B00E836B0 /* AppStorePaymentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58DF28A42417CB4B00E836B0 /* AppStorePaymentManager.swift */; }; 58E5BC2624FEB6DB00A53A76 /* AccountViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 58E5BC2524FEB6DB00A53A76 /* AccountViewController.xib */; }; 58E6771F24ADFE7800AA26E7 /* SettingsNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58E6771E24ADFE7800AA26E7 /* SettingsNavigationController.swift */; }; @@ -357,6 +357,7 @@ 58AEEF6A2344A46200C9BBD5 /* TunnelSettingsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelSettingsManager.swift; sourceTree = "<group>"; }; 58B0A2A0238EE67E00BC001D /* MullvadVPNTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MullvadVPNTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58B0A2A4238EE67E00BC001D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; + 58B43C1825F77DB60002C8C3 /* ConnectMainContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectMainContentView.swift; sourceTree = "<group>"; }; 58B8743122B25A7600015324 /* WireguardAssociatedAddresses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireguardAssociatedAddresses.swift; sourceTree = "<group>"; }; 58B8743722B25EAB00015324 /* PacketTunnelSettingsGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelSettingsGenerator.swift; sourceTree = "<group>"; }; 58B9814D24FEA70D00C0D59E /* WireguardKeysViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WireguardKeysViewController.xib; sourceTree = "<group>"; }; @@ -393,7 +394,6 @@ 58D0C79D23F1CEBA00FE9BA7 /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnapshotHelper.swift; sourceTree = "<group>"; }; 58D0C79F23F1CECF00FE9BA7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 58D0C7A023F1CECF00FE9BA7 /* MullvadVPNScreenshots.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MullvadVPNScreenshots.swift; sourceTree = "<group>"; }; - 58D9AF6A2501111800B6FAB5 /* ConnectViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ConnectViewController.xib; sourceTree = "<group>"; }; 58DF28A42417CB4B00E836B0 /* AppStorePaymentManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStorePaymentManager.swift; sourceTree = "<group>"; }; 58E5BC2524FEB6DB00A53A76 /* AccountViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountViewController.xib; sourceTree = "<group>"; }; 58E6771E24ADFE7800AA26E7 /* SettingsNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsNavigationController.swift; sourceTree = "<group>"; }; @@ -564,7 +564,7 @@ 58F840B12464491D0044E708 /* ChainedError.swift */, 58A1AA8B23F5584B009F7EA6 /* ConnectionPanelView.swift */, 58CCA00F224249A1004F3011 /* ConnectViewController.swift */, - 58D9AF6A2501111800B6FAB5 /* ConnectViewController.xib */, + 58B43C1825F77DB60002C8C3 /* ConnectMainContentView.swift */, 58A99ED2240014A0006599E9 /* ConsentViewController.swift */, 58AB9DEB2501040C006C5526 /* ConsentViewController.xib */, 5896AE83246D5889005B36CB /* CustomDateComponentsFormatting.swift */, @@ -873,7 +873,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 58D9AF6B2501111800B6FAB5 /* ConnectViewController.xib in Resources */, 58AB9DEE25010636006C5526 /* LoginViewController.xib in Resources */, 58F3C0A624A50157003E76BE /* relays.json in Resources */, 58CE5E6E224146210008646E /* LaunchScreen.storyboard in Resources */, @@ -1051,6 +1050,7 @@ 581503A324D6F1EC00C9C50E /* ChainedError+Logger.swift in Sources */, 58FD5BF024238EB300112C88 /* SKProduct+Formatting.swift in Sources */, 58C3B06724EA768100C0348E /* LogStreamerViewController.swift in Sources */, + 58B43C1925F77DB60002C8C3 /* ConnectMainContentView.swift in Sources */, 58561C99239A5D1500BD6B5E /* IPEndpoint.swift in Sources */, 58FD5BF22424F7D700112C88 /* UserInterfaceInteractionRestriction.swift in Sources */, 5811DE50239014550011EB53 /* NEVPNStatus+Debug.swift in Sources */, diff --git a/ios/MullvadVPN/ConnectMainContentView.swift b/ios/MullvadVPN/ConnectMainContentView.swift new file mode 100644 index 0000000000..95e97128e3 --- /dev/null +++ b/ios/MullvadVPN/ConnectMainContentView.swift @@ -0,0 +1,147 @@ +// +// ConnectMainContentView.swift +// MullvadVPN +// +// Created by pronebird on 09/03/2021. +// Copyright © 2021 Mullvad VPN AB. All rights reserved. +// + +import UIKit + +class ConnectMainContentView: UIView { + enum ActionButton { + case connect + case disconnect + case selectLocation + } + + let secureLabel = makeBoldTextLabel(ofSize: 20) + let countryLabel = makeBoldTextLabel(ofSize: 34) + let cityLabel = makeBoldTextLabel(ofSize: 34) + + lazy var connectionPanel: ConnectionPanelView = { + let view = ConnectionPanelView() + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + + lazy var buttonsStackView: UIStackView = { + let stackView = UIStackView() + stackView.spacing = 16 + stackView.axis = .vertical + stackView.translatesAutoresizingMaskIntoConstraints = false + return stackView + }() + + lazy var connectButton: AppButton = { + let button = AppButton(style: .success) + button.translatesAutoresizingMaskIntoConstraints = false + button.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold) + return button + }() + + lazy var selectLocationButton: AppButton = { + let button = AppButton(style: .translucentNeutral) + button.accessibilityIdentifier = "SelectLocationButton" + button.translatesAutoresizingMaskIntoConstraints = false + button.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold) + return button + }() + + let splitDisconnectButton: DisconnectSplitButton = { + let button = DisconnectSplitButton() + button.primaryButton.accessibilityIdentifier = "DisconnectButton" + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() + + let containerView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + + override init(frame: CGRect) { + super.init(frame: frame) + + backgroundColor = .primaryColor + layoutMargins = UIEdgeInsets(top: 24, left: 24, bottom: 24, right: 24) + + addSubviews() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func setActionButtons(_ actionButtons: [ActionButton]) { + let views = actionButtons.map { self.view(forActionButton: $0) } + + setArrangedButtons(views) + } + + private class func makeBoldTextLabel(ofSize fontSize: CGFloat) -> UILabel { + let textLabel = UILabel() + textLabel.translatesAutoresizingMaskIntoConstraints = false + textLabel.font = UIFont.boldSystemFont(ofSize: fontSize) + textLabel.textColor = .white + return textLabel + } + + private func addSubviews() { + addSubview(containerView) + [secureLabel, countryLabel, cityLabel, connectionPanel, buttonsStackView].forEach { containerView.addSubview($0) } + + NSLayoutConstraint.activate([ + containerView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor), + containerView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor), + containerView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor), + containerView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor), + + secureLabel.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor), + secureLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), + secureLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), + + countryLabel.topAnchor.constraint(equalTo: secureLabel.bottomAnchor, constant: 8), + countryLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), + countryLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), + + cityLabel.topAnchor.constraint(equalTo: countryLabel.bottomAnchor, constant: 8), + cityLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), + cityLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), + + connectionPanel.topAnchor.constraint(equalTo: cityLabel.bottomAnchor, constant: 8), + connectionPanel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), + connectionPanel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), + + buttonsStackView.topAnchor.constraint(equalTo: connectionPanel.bottomAnchor, constant: 24), + buttonsStackView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), + buttonsStackView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), + buttonsStackView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor) + ]) + } + + private func setArrangedButtons(_ newButtons: [UIView]) { + buttonsStackView.arrangedSubviews.forEach { (button) in + if !newButtons.contains(button) { + buttonsStackView.removeArrangedSubview(button) + button.removeFromSuperview() + } + } + + newButtons.forEach { (button) in + buttonsStackView.addArrangedSubview(button) + } + } + + private func view(forActionButton actionButton: ActionButton) -> UIView { + switch actionButton { + case .connect: + return connectButton + case .disconnect: + return splitDisconnectButton + case .selectLocation: + return selectLocationButton + } + } +} diff --git a/ios/MullvadVPN/ConnectViewController.swift b/ios/MullvadVPN/ConnectViewController.swift index b5cbb08d05..f8968b1ad3 100644 --- a/ios/MullvadVPN/ConnectViewController.swift +++ b/ios/MullvadVPN/ConnectViewController.swift @@ -12,20 +12,15 @@ import Logging class ConnectViewController: UIViewController, RootContainment, TunnelObserver { - @IBOutlet var secureLabel: UILabel! - @IBOutlet var countryLabel: UILabel! - @IBOutlet var cityLabel: UILabel! - @IBOutlet var connectionPanel: ConnectionPanelView! - @IBOutlet var buttonsStackView: UIStackView! + private lazy var mainContentView: ConnectMainContentView = { + let view = ConnectMainContentView(frame: UIScreen.main.bounds) + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() private var relayConstraints: RelayConstraints? private let logger = Logger(label: "ConnectViewController") - - private let connectButton = AppButton(style: .success) - private let selectLocationButton = AppButton(style: .translucentNeutral) - private let splitDisconnectButtonView = DisconnectSplitButton() - private let alertPresenter = AlertPresenter() override var preferredStatusBarStyle: UIStatusBarStyle { @@ -49,9 +44,8 @@ class ConnectViewController: UIViewController, RootContainment, TunnelObserver private var tunnelState: TunnelState = .disconnected { didSet { setNeedsHeaderBarStyleAppearanceUpdate() - updateSecureLabel() updateTunnelConnectionInfo() - updateButtons() + updateUserInterfaceForTunnelStateChange() } } @@ -60,19 +54,20 @@ class ConnectViewController: UIViewController, RootContainment, TunnelObserver override func viewDidLoad() { super.viewDidLoad() - for button in [connectButton, selectLocationButton] { - button.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold) - } - - selectLocationButton.accessibilityIdentifier = "SelectLocationButton" - splitDisconnectButtonView.primaryButton.accessibilityIdentifier = "DisconnectButton" + mainContentView.connectionPanel.collapseButton.addTarget(self, action: #selector(handleConnectionPanelButton(_:)), for: .touchUpInside) + mainContentView.connectButton.addTarget(self, action: #selector(handleConnect(_:)), for: .touchUpInside) + mainContentView.splitDisconnectButton.primaryButton.addTarget(self, action: #selector(handleDisconnect(_:)), for: .touchUpInside) + mainContentView.splitDisconnectButton.secondaryButton.addTarget(self, action: #selector(handleReconnect(_:)), for: .touchUpInside) - connectionPanel.collapseButton.addTarget(self, action: #selector(handleConnectionPanelButton(_:)), for: .touchUpInside) - connectButton.addTarget(self, action: #selector(handleConnect(_:)), for: .touchUpInside) - splitDisconnectButtonView.primaryButton.addTarget(self, action: #selector(handleDisconnect(_:)), for: .touchUpInside) - splitDisconnectButtonView.secondaryButton.addTarget(self, action: #selector(handleReconnect(_:)), for: .touchUpInside) + mainContentView.selectLocationButton.addTarget(self, action: #selector(handleSelectLocation(_:)), for: .touchUpInside) - selectLocationButton.addTarget(self, action: #selector(handleSelectLocation(_:)), for: .touchUpInside) + view.addSubview(mainContentView) + NSLayoutConstraint.activate([ + mainContentView.topAnchor.constraint(equalTo: view.topAnchor), + mainContentView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + mainContentView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + mainContentView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ]) TunnelManager.shared.addObserver(self) self.tunnelState = TunnelManager.shared.tunnelState @@ -100,44 +95,14 @@ class ConnectViewController: UIViewController, RootContainment, TunnelObserver // MARK: - Private - private func updateButtons() { - switch tunnelState { - case .disconnected, .disconnecting: - selectLocationButton.setTitle(NSLocalizedString("Select location", comment: ""), for: .normal) - connectButton.setTitle(NSLocalizedString("Secure connection", comment: ""), for: .normal) - - setArrangedButtons([selectLocationButton, connectButton]) - - case .connecting: - selectLocationButton.setTitle(NSLocalizedString("Switch location", comment: ""), for: .normal) - splitDisconnectButtonView.primaryButton.setTitle(NSLocalizedString("Cancel", comment: ""), for: .normal) - - setArrangedButtons([selectLocationButton, splitDisconnectButtonView]) - - case .connected, .reconnecting: - selectLocationButton.setTitle(NSLocalizedString("Switch location", comment: ""), for: .normal) - splitDisconnectButtonView.primaryButton.setTitle(NSLocalizedString("Disconnect", comment: ""), for: .normal) - - setArrangedButtons([selectLocationButton, splitDisconnectButtonView]) - } - } - - private func setArrangedButtons(_ newButtons: [UIView]) { - buttonsStackView.arrangedSubviews.forEach { (button) in - if !newButtons.contains(button) { - buttonsStackView.removeArrangedSubview(button) - button.removeFromSuperview() - } - } - - newButtons.forEach { (button) in - buttonsStackView.addArrangedSubview(button) - } - } + private func updateUserInterfaceForTunnelStateChange() { + mainContentView.secureLabel.text = tunnelState.localizedTitleForSecureLabel.uppercased() + mainContentView.secureLabel.textColor = tunnelState.textColorForSecureLabel - private func updateSecureLabel() { - secureLabel.text = tunnelState.textForSecureLabel().uppercased() - secureLabel.textColor = tunnelState.textColorForSecureLabel() + mainContentView.connectButton.setTitle(tunnelState.localizedTitleForConnectButton, for: .normal) + mainContentView.selectLocationButton.setTitle(tunnelState.localizedTitleForSelectLocationButton, for: .normal) + mainContentView.splitDisconnectButton.primaryButton.setTitle(tunnelState.localizedTitleForDisconnectButton, for: .normal) + mainContentView.setActionButtons(tunnelState.actionButtons) } private func attributedStringForLocation(string: String) -> NSAttributedString { @@ -152,21 +117,21 @@ class ConnectViewController: UIViewController, RootContainment, TunnelObserver switch tunnelState { case .connected(let connectionInfo), .reconnecting(let connectionInfo): - cityLabel.attributedText = attributedStringForLocation(string: connectionInfo.location.city) - countryLabel.attributedText = attributedStringForLocation(string: connectionInfo.location.country) + mainContentView.cityLabel.attributedText = attributedStringForLocation(string: connectionInfo.location.city) + mainContentView.countryLabel.attributedText = attributedStringForLocation(string: connectionInfo.location.country) - connectionPanel.dataSource = ConnectionPanelData( + mainContentView.connectionPanel.dataSource = ConnectionPanelData( inAddress: "\(connectionInfo.ipv4Relay) UDP", outAddress: nil ) - connectionPanel.isHidden = false - connectionPanel.collapseButton.setTitle(connectionInfo.hostname, for: .normal) + mainContentView.connectionPanel.isHidden = false + mainContentView.connectionPanel.collapseButton.setTitle(connectionInfo.hostname, for: .normal) case .connecting, .disconnected, .disconnecting: - cityLabel.attributedText = attributedStringForLocation(string: " ") - countryLabel.attributedText = attributedStringForLocation(string: " ") - connectionPanel.dataSource = nil - connectionPanel.isHidden = true + mainContentView.cityLabel.attributedText = attributedStringForLocation(string: " ") + mainContentView.countryLabel.attributedText = attributedStringForLocation(string: " ") + mainContentView.connectionPanel.dataSource = nil + mainContentView.connectionPanel.isHidden = true } } @@ -304,7 +269,7 @@ class ConnectViewController: UIViewController, RootContainment, TunnelObserver // MARK: - Actions @objc func handleConnectionPanelButton(_ sender: Any) { - connectionPanel.toggleConnectionInfoVisibility() + mainContentView.connectionPanel.toggleConnectionInfoVisibility() } @objc func handleConnect(_ sender: Any) { @@ -331,7 +296,7 @@ class ConnectViewController: UIViewController, RootContainment, TunnelObserver private extension TunnelState { - func textColorForSecureLabel() -> UIColor { + var textColorForSecureLabel: UIColor { switch self { case .connecting, .reconnecting: return .white @@ -344,7 +309,7 @@ private extension TunnelState { } } - func textForSecureLabel() -> String { + var localizedTitleForSecureLabel: String { switch self { case .connecting, .reconnecting: return NSLocalizedString("Creating secure connection", comment: "") @@ -357,4 +322,38 @@ private extension TunnelState { } } + var localizedTitleForSelectLocationButton: String? { + switch self { + case .disconnected, .disconnecting: + return NSLocalizedString("Select location", comment: "") + case .connecting, .connected, .reconnecting: + return NSLocalizedString("Switch location", comment: "") + } + } + + var localizedTitleForConnectButton: String? { + return NSLocalizedString("Secure connection", comment: "") + } + + var localizedTitleForDisconnectButton: String? { + switch self { + case .connecting: + return NSLocalizedString("Cancel", comment: "") + case .connected, .reconnecting: + return NSLocalizedString("Disconnect", comment: "") + case .disconnecting, .disconnected: + return nil + } + } + + var actionButtons: [ConnectMainContentView.ActionButton] { + switch self { + case .disconnected, .disconnecting: + return [.selectLocation, .connect] + + case .connecting, .connected, .reconnecting: + return [.selectLocation, .disconnect] + } + } + } diff --git a/ios/MullvadVPN/ConnectViewController.xib b/ios/MullvadVPN/ConnectViewController.xib deleted file mode 100644 index ff2f253c22..0000000000 --- a/ios/MullvadVPN/ConnectViewController.xib +++ /dev/null @@ -1,113 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> - <device id="retina6_1" orientation="portrait" appearance="light"/> - <dependencies> - <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/> - <capability name="Named colors" minToolsVersion="9.0"/> - <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="ConnectViewController" customModule="MullvadVPN" customModuleProvider="target"> - <connections> - <outlet property="buttonsStackView" destination="tVZ-jT-d0h" id="IRm-TE-iJs"/> - <outlet property="cityLabel" destination="8Qe-Us-gxU" id="qAs-MJ-Quv"/> - <outlet property="connectionPanel" destination="h6t-ky-9gm" id="hOY-G9-IVQ"/> - <outlet property="countryLabel" destination="neK-xr-40H" id="tNC-OD-PTx"/> - <outlet property="secureLabel" destination="dus-AY-JC0" id="PMW-GI-4ga"/> - <outlet property="view" destination="bFH-8p-vRl" id="jVw-4H-ccF"/> - </connections> - </placeholder> - <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> - <view contentMode="scaleToFill" id="bFH-8p-vRl"> - <rect key="frame" x="0.0" y="0.0" width="414" height="896"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> - <subviews> - <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="SON-pD-ZGn"> - <rect key="frame" x="24" y="502" width="366" height="212"/> - <subviews> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SECURE CONNECTION" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dus-AY-JC0"> - <rect key="frame" x="0.0" y="0.0" width="366" height="24"/> - <accessibility key="accessibilityConfiguration" identifier="SecureConnectionLabel"/> - <fontDescription key="fontDescription" type="boldSystem" pointSize="20"/> - <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - <nil key="highlightedColor"/> - </label> - <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="daZ-9L-RFn"> - <rect key="frame" x="0.0" y="32" width="366" height="82"/> - <subviews> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Stockholm" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8Qe-Us-gxU"> - <rect key="frame" x="0.0" y="0.0" width="366" height="41"/> - <fontDescription key="fontDescription" type="boldSystem" pointSize="34"/> - <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - <nil key="highlightedColor"/> - </label> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Sweden" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsLetterSpacingToFitWidth="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="neK-xr-40H"> - <rect key="frame" x="0.0" y="41" width="366" height="41"/> - <fontDescription key="fontDescription" type="boldSystem" pointSize="34"/> - <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - <nil key="highlightedColor"/> - </label> - </subviews> - </stackView> - <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="mAs-zy-aF9"> - <rect key="frame" x="0.0" y="122" width="366" height="90"/> - <subviews> - <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="h6t-ky-9gm" customClass="ConnectionPanelView" customModule="MullvadVPN" customModuleProvider="target"> - <rect key="frame" x="0.0" y="0.0" width="366" height="90"/> - <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - <constraints> - <constraint firstAttribute="height" constant="90" placeholder="YES" id="sqc-lF-rCp"/> - </constraints> - </view> - </subviews> - <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - <constraints> - <constraint firstAttribute="bottom" secondItem="h6t-ky-9gm" secondAttribute="bottom" id="gde-uU-FXR"/> - <constraint firstAttribute="trailing" secondItem="h6t-ky-9gm" secondAttribute="trailing" id="hyx-Rc-2zS"/> - <constraint firstItem="h6t-ky-9gm" firstAttribute="leading" secondItem="mAs-zy-aF9" secondAttribute="leading" id="ivP-qV-nIn"/> - <constraint firstItem="h6t-ky-9gm" firstAttribute="top" secondItem="mAs-zy-aF9" secondAttribute="top" id="zG4-Um-x5m"/> - </constraints> - </view> - </subviews> - </stackView> - <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="82Y-rR-Igf"> - <rect key="frame" x="24" y="738" width="366" height="100"/> - <subviews> - <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="tVZ-jT-d0h"> - <rect key="frame" x="0.0" y="0.0" width="366" height="100"/> - <constraints> - <constraint firstAttribute="height" constant="100" placeholder="YES" id="VS7-pq-Idz"/> - </constraints> - </stackView> - </subviews> - <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - <constraints> - <constraint firstItem="tVZ-jT-d0h" firstAttribute="top" secondItem="82Y-rR-Igf" secondAttribute="top" id="1YE-mx-7t7"/> - <constraint firstItem="tVZ-jT-d0h" firstAttribute="leading" secondItem="82Y-rR-Igf" secondAttribute="leading" id="Dab-DT-04W"/> - <constraint firstAttribute="bottom" secondItem="tVZ-jT-d0h" secondAttribute="bottom" id="Sjj-UF-9Xr"/> - <constraint firstAttribute="trailing" secondItem="tVZ-jT-d0h" secondAttribute="trailing" id="cOe-Ju-VcI"/> - </constraints> - </view> - </subviews> - <color key="backgroundColor" name="Primary"/> - <constraints> - <constraint firstItem="Rzj-xL-crv" firstAttribute="bottom" secondItem="82Y-rR-Igf" secondAttribute="bottom" constant="24" id="D4A-Ij-Eip"/> - <constraint firstItem="Rzj-xL-crv" firstAttribute="trailing" secondItem="82Y-rR-Igf" secondAttribute="trailing" constant="24" id="DPX-JT-0Bx"/> - <constraint firstItem="SON-pD-ZGn" firstAttribute="leading" secondItem="bFH-8p-vRl" secondAttribute="leadingMargin" id="LSL-Go-oXb"/> - <constraint firstItem="82Y-rR-Igf" firstAttribute="leading" secondItem="Rzj-xL-crv" secondAttribute="leading" constant="24" id="UWY-XY-Njv"/> - <constraint firstAttribute="trailingMargin" secondItem="SON-pD-ZGn" secondAttribute="trailing" id="Vhs-Sr-QUI"/> - <constraint firstItem="82Y-rR-Igf" firstAttribute="top" secondItem="SON-pD-ZGn" secondAttribute="bottom" constant="24" id="WhU-py-uqj"/> - </constraints> - <edgeInsets key="layoutMargins" top="0.0" left="24" bottom="24" right="24"/> - <viewLayoutGuide key="safeArea" id="Rzj-xL-crv"/> - <point key="canvasLocation" x="139" y="153"/> - </view> - </objects> - <resources> - <namedColor name="Primary"> - <color red="0.16078431372549021" green="0.30196078431372547" blue="0.45098039215686275" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> - </namedColor> - </resources> -</document> |
