diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2020-02-17 16:02:55 +0100 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2020-02-18 13:02:48 +0100 |
| commit | 8cabbf30adedaea8969080804c2e335e0625663b (patch) | |
| tree | 3dd98c99cdf3604e6d79996fc3ce64cae38648de /ios/MullvadVPN/ConnectionPanelView.swift | |
| parent | 354c7feec88797e6696dbbc7a5177187baae3a2e (diff) | |
| download | mullvadvpn-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.swift | 240 |
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 + } + +} |
