summaryrefslogtreecommitdiffhomepage
path: root/ios/MullvadVPN/ConnectionPanelView.swift
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2020-02-17 16:02:55 +0100
committerAndrej Mihajlov <and@mullvad.net>2020-02-18 13:02:48 +0100
commit8cabbf30adedaea8969080804c2e335e0625663b (patch)
tree3dd98c99cdf3604e6d79996fc3ce64cae38648de /ios/MullvadVPN/ConnectionPanelView.swift
parent354c7feec88797e6696dbbc7a5177187baae3a2e (diff)
downloadmullvadvpn-8cabbf30adedaea8969080804c2e335e0625663b.tar.xz
mullvadvpn-8cabbf30adedaea8969080804c2e335e0625663b.zip
Show relay location and connection info
Diffstat (limited to 'ios/MullvadVPN/ConnectionPanelView.swift')
-rw-r--r--ios/MullvadVPN/ConnectionPanelView.swift240
1 files changed, 240 insertions, 0 deletions
diff --git a/ios/MullvadVPN/ConnectionPanelView.swift b/ios/MullvadVPN/ConnectionPanelView.swift
new file mode 100644
index 0000000000..85ed53a12e
--- /dev/null
+++ b/ios/MullvadVPN/ConnectionPanelView.swift
@@ -0,0 +1,240 @@
+//
+// ConnectionPanelView.swift
+// MullvadVPN
+//
+// Created by pronebird on 12/02/2020.
+// Copyright © 2020 Mullvad VPN AB. All rights reserved.
+//
+
+import Foundation
+import UIKit
+
+struct ConnectionPanelData {
+ var inAddress: String
+ var outAddress: String?
+}
+
+class ConnectionPanelView: UIView {
+
+ var dataSource: ConnectionPanelData? {
+ didSet {
+ didChangeDataSource()
+ }
+ }
+
+ var showsConnectionInfo = false {
+ didSet {
+ updateConnectionInfoVisibility()
+ }
+ }
+
+ let collapseButton: ConnectionPanelCollapseButton = {
+ let button = ConnectionPanelCollapseButton(type: .custom)
+ button.translatesAutoresizingMaskIntoConstraints = false
+ button.tintColor = .white
+ return button
+ }()
+
+ private let protocolRow = ConnectionPanelProtocolTypeRow()
+ private let inAddressRow = ConnectionPanelAddressRow()
+ private let outAddressRow = ConnectionPanelAddressRow()
+
+ private lazy var stackView: UIStackView = {
+ let stackView = UIStackView(arrangedSubviews: [protocolRow, inAddressRow, outAddressRow])
+ stackView.axis = .vertical
+ stackView.translatesAutoresizingMaskIntoConstraints = false
+ return stackView
+ }()
+
+ private let textLabelLayoutGuide: UILayoutGuide = {
+ let layoutGuide = UILayoutGuide()
+ layoutGuide.identifier = "TextLabelLayoutGuide"
+ return layoutGuide
+ }()
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ commonInit()
+ }
+
+ required init?(coder: NSCoder) {
+ super.init(coder: coder)
+ commonInit()
+ }
+
+ func didChangeDataSource() {
+ inAddressRow.detailTextLabel.text = dataSource?.inAddress
+ outAddressRow.detailTextLabel.text = dataSource?.outAddress
+ }
+
+ func toggleConnectionInfoVisibility() {
+ showsConnectionInfo = !showsConnectionInfo
+ }
+
+ private func updateConnectionInfoVisibility() {
+ stackView.isHidden = showsConnectionInfo
+ collapseButton.style = showsConnectionInfo ? .down : .up
+ }
+
+ private func commonInit() {
+ protocolRow.translatesAutoresizingMaskIntoConstraints = false
+ inAddressRow.translatesAutoresizingMaskIntoConstraints = false
+ outAddressRow.translatesAutoresizingMaskIntoConstraints = false
+
+ // TODO: Unhide it when we have out address
+ outAddressRow.isHidden = true
+
+ protocolRow.textLabel.text = NSLocalizedString("WireGuard", comment: "")
+ inAddressRow.textLabel.text = NSLocalizedString("In", comment: "")
+ outAddressRow.textLabel.text = NSLocalizedString("Out", comment: "")
+
+ addSubview(collapseButton)
+ addSubview(stackView)
+ addLayoutGuide(textLabelLayoutGuide)
+
+ NSLayoutConstraint.activate([
+ collapseButton.topAnchor.constraint(equalTo: topAnchor),
+ collapseButton.leadingAnchor.constraint(equalTo: leadingAnchor),
+ collapseButton.trailingAnchor.constraint(equalTo: trailingAnchor),
+
+ stackView.topAnchor.constraint(equalTo: collapseButton.bottomAnchor, constant: 4),
+ stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
+ stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
+ stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
+
+ // Align all text labels with the guide, so that they maintain equal width
+ textLabelLayoutGuide.trailingAnchor
+ .constraint(equalTo: inAddressRow.textLabel.trailingAnchor),
+ textLabelLayoutGuide.trailingAnchor
+ .constraint(equalTo: outAddressRow.textLabel.trailingAnchor)
+ ])
+ }
+}
+
+class ConnectionPanelProtocolTypeRow: UIView {
+ let textLabel = UILabel()
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+
+ textLabel.translatesAutoresizingMaskIntoConstraints = false
+ textLabel.font = UIFont.systemFont(ofSize: 17)
+ textLabel.textColor = .white
+
+ addSubview(textLabel)
+
+ NSLayoutConstraint.activate([
+ textLabel.topAnchor.constraint(equalTo: topAnchor),
+ textLabel.bottomAnchor.constraint(equalTo: bottomAnchor),
+ textLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
+ textLabel.trailingAnchor.constraint(equalTo: trailingAnchor)
+ ])
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
+
+class ConnectionPanelAddressRow: UIView {
+ let textLabel = UILabel()
+ let detailTextLabel = UILabel()
+ let stackView: UIStackView
+
+ override init(frame: CGRect) {
+
+ let font = UIFont.systemFont(ofSize: 17)
+
+ textLabel.font = font
+ textLabel.textColor = .white
+ textLabel.translatesAutoresizingMaskIntoConstraints = false
+ textLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
+
+ detailTextLabel.font = font
+ detailTextLabel.textColor = .white
+ detailTextLabel.translatesAutoresizingMaskIntoConstraints = false
+
+ stackView = UIStackView(arrangedSubviews: [textLabel, detailTextLabel])
+ stackView.spacing = UIStackView.spacingUseSystem
+ stackView.translatesAutoresizingMaskIntoConstraints = false
+
+ super.init(frame: frame)
+
+ addSubview(stackView)
+
+ NSLayoutConstraint.activate([
+ stackView.topAnchor.constraint(equalTo: topAnchor),
+ stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
+ stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
+ stackView.trailingAnchor.constraint(equalTo: trailingAnchor)
+ ])
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
+
+class ConnectionPanelCollapseButton: UIButton {
+
+ enum Style {
+ case up, down
+
+ var image: UIImage {
+ switch self {
+ case .up:
+ return UIImage(imageLiteralResourceName: "IconChevronUp")
+ case .down:
+ return UIImage(imageLiteralResourceName: "IconChevronDown")
+ }
+ }
+ }
+
+ var style = Style.up {
+ didSet {
+ updateButtonImage()
+ }
+ }
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+
+ commonInit()
+ updateButtonImage()
+ }
+
+ required init?(coder: NSCoder) {
+ super.init(coder: coder)
+
+ commonInit()
+ updateButtonImage()
+ }
+
+ private func commonInit() {
+ setTitleColor(UIColor.white, for: .normal)
+ setTitleColor(UIColor.lightGray, for: .highlighted)
+ setTitleColor(UIColor.lightGray, for: .disabled)
+ }
+
+ private func updateButtonImage() {
+ setImage(style.image, for: .normal)
+ }
+
+ override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
+ let titleRect = self.titleRect(forContentRect: contentRect)
+ var imageRect = super.imageRect(forContentRect: contentRect)
+
+ imageRect.origin.x = titleRect.maxX
+
+ return imageRect
+ }
+
+ override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
+ var titleRect = super.titleRect(forContentRect: contentRect)
+
+ titleRect.origin.x = 0
+
+ return titleRect
+ }
+
+}