Nuke trailing spaces
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
@@ -53,7 +53,7 @@ enum TunnelsManagerActivationAttemptError: WireGuardAppError {
|
||||
enum TunnelsManagerActivationError: WireGuardAppError {
|
||||
case activationFailed(wasOnDemandEnabled: Bool)
|
||||
case activationFailedWithExtensionError(title: String, message: String, wasOnDemandEnabled: Bool)
|
||||
|
||||
|
||||
var alertText: AlertText {
|
||||
switch self {
|
||||
case .activationFailed(let wasOnDemandEnabled):
|
||||
|
||||
@@ -12,7 +12,7 @@ import NetworkExtension
|
||||
case reasserting // Not a possible state at present
|
||||
case restarting // Restarting tunnel (done after saving modifications to an active tunnel)
|
||||
case waiting // Waiting for another tunnel to be brought down
|
||||
|
||||
|
||||
init(from systemStatus: NEVPNStatus) {
|
||||
switch systemStatus {
|
||||
case .connected:
|
||||
|
||||
@@ -41,7 +41,7 @@ class TunnelsManager {
|
||||
completionHandler(.failure(TunnelsManagerError.systemErrorOnListingTunnels(systemError: error)))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let tunnelManagers = managers ?? []
|
||||
tunnelManagers.forEach { tunnelManager in
|
||||
if (tunnelManager.protocolConfiguration as? NETunnelProviderProtocol)?.migrateConfigurationIfNeeded() == true {
|
||||
@@ -78,9 +78,9 @@ class TunnelsManager {
|
||||
completionHandler(.failure(TunnelsManagerError.systemErrorOnAddTunnel(systemError: error!)))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
guard let self = self else { return }
|
||||
|
||||
|
||||
let tunnel = TunnelContainer(tunnel: tunnelProviderManager)
|
||||
self.tunnels.append(tunnel)
|
||||
self.tunnels.sort { $0.name < $1.name }
|
||||
@@ -126,7 +126,7 @@ class TunnelsManager {
|
||||
tunnelProviderManager.protocolConfiguration = NETunnelProviderProtocol(tunnelConfiguration: tunnelConfiguration)
|
||||
tunnelProviderManager.localizedDescription = (tunnelConfiguration).interface.name
|
||||
tunnelProviderManager.isEnabled = true
|
||||
|
||||
|
||||
let isActivatingOnDemand = !tunnelProviderManager.isOnDemandEnabled && activateOnDemandSetting.isActivateOnDemandEnabled
|
||||
activateOnDemandSetting.apply(on: tunnelProviderManager)
|
||||
|
||||
@@ -137,7 +137,7 @@ class TunnelsManager {
|
||||
return
|
||||
}
|
||||
guard let self = self else { return }
|
||||
|
||||
|
||||
if isNameChanged {
|
||||
let oldIndex = self.tunnels.firstIndex(of: tunnel)!
|
||||
self.tunnels.sort { $0.name < $1.name }
|
||||
@@ -351,11 +351,11 @@ class TunnelContainer: NSObject {
|
||||
var tunnelConfiguration: TunnelConfiguration? {
|
||||
return (tunnelProvider.protocolConfiguration as? NETunnelProviderProtocol)?.tunnelConfiguration(name: tunnelProvider.localizedDescription)
|
||||
}
|
||||
|
||||
|
||||
var activateOnDemandSetting: ActivateOnDemandSetting {
|
||||
return ActivateOnDemandSetting(from: tunnelProvider)
|
||||
}
|
||||
|
||||
|
||||
init(tunnel: NETunnelProviderManager) {
|
||||
name = tunnel.localizedDescription ?? "Unnamed"
|
||||
let status = TunnelStatus(from: tunnel.connection.status)
|
||||
|
||||
@@ -10,42 +10,42 @@ class BorderedTextButton: UIView {
|
||||
button.titleLabel?.adjustsFontForContentSizeCategory = true
|
||||
return button
|
||||
}()
|
||||
|
||||
|
||||
override var intrinsicContentSize: CGSize {
|
||||
let buttonSize = button.intrinsicContentSize
|
||||
return CGSize(width: buttonSize.width + 32, height: buttonSize.height + 16)
|
||||
}
|
||||
|
||||
|
||||
var title: String {
|
||||
get { return button.title(for: .normal) ?? "" }
|
||||
set(value) { button.setTitle(value, for: .normal) }
|
||||
}
|
||||
|
||||
|
||||
var onTapped: (() -> Void)?
|
||||
|
||||
|
||||
init() {
|
||||
super.init(frame: CGRect.zero)
|
||||
|
||||
|
||||
layer.borderWidth = 1
|
||||
layer.cornerRadius = 5
|
||||
layer.borderColor = button.tintColor.cgColor
|
||||
|
||||
|
||||
addSubview(button)
|
||||
button.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
button.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||
button.centerYAnchor.constraint(equalTo: centerYAnchor)
|
||||
])
|
||||
|
||||
|
||||
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
|
||||
}
|
||||
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
@objc func buttonTapped() {
|
||||
onTapped?()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -13,20 +13,20 @@ class ButtonCell: UITableViewCell {
|
||||
set(value) { button.tintColor = value ? .red : buttonStandardTintColor }
|
||||
}
|
||||
var onTapped: (() -> Void)?
|
||||
|
||||
|
||||
let button: UIButton = {
|
||||
let button = UIButton(type: .system)
|
||||
button.titleLabel?.font = UIFont.preferredFont(forTextStyle: .body)
|
||||
button.titleLabel?.adjustsFontForContentSizeCategory = true
|
||||
return button
|
||||
}()
|
||||
|
||||
|
||||
var buttonStandardTintColor: UIColor
|
||||
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
buttonStandardTintColor = button.tintColor
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
|
||||
contentView.addSubview(button)
|
||||
button.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
@@ -34,18 +34,18 @@ class ButtonCell: UITableViewCell {
|
||||
contentView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: button.bottomAnchor),
|
||||
button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor)
|
||||
])
|
||||
|
||||
|
||||
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
|
||||
}
|
||||
|
||||
|
||||
@objc func buttonTapped() {
|
||||
onTapped?()
|
||||
}
|
||||
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
buttonText = ""
|
||||
|
||||
@@ -13,16 +13,16 @@ class CheckmarkCell: UITableViewCell {
|
||||
accessoryType = isChecked ? .checkmark : .none
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
isChecked = false
|
||||
super.init(style: .default, reuseIdentifier: reuseIdentifier)
|
||||
}
|
||||
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
message = ""
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import UIKit
|
||||
|
||||
class KeyValueCell: UITableViewCell {
|
||||
|
||||
|
||||
let keyLabel: UILabel = {
|
||||
let keyLabel = UILabel()
|
||||
keyLabel.font = UIFont.preferredFont(forTextStyle: .body)
|
||||
@@ -13,7 +13,7 @@ class KeyValueCell: UITableViewCell {
|
||||
keyLabel.textAlignment = .left
|
||||
return keyLabel
|
||||
}()
|
||||
|
||||
|
||||
let valueLabelScrollView: UIScrollView = {
|
||||
let scrollView = UIScrollView(frame: .zero)
|
||||
scrollView.isDirectionalLockEnabled = true
|
||||
@@ -21,7 +21,7 @@ class KeyValueCell: UITableViewCell {
|
||||
scrollView.showsVerticalScrollIndicator = false
|
||||
return scrollView
|
||||
}()
|
||||
|
||||
|
||||
let valueTextField: UITextField = {
|
||||
let valueTextField = UITextField()
|
||||
valueTextField.textAlignment = .right
|
||||
@@ -34,7 +34,7 @@ class KeyValueCell: UITableViewCell {
|
||||
valueTextField.textColor = .gray
|
||||
return valueTextField
|
||||
}()
|
||||
|
||||
|
||||
var copyableGesture = true
|
||||
|
||||
var key: String {
|
||||
@@ -53,7 +53,7 @@ class KeyValueCell: UITableViewCell {
|
||||
get { return valueTextField.keyboardType }
|
||||
set(value) { valueTextField.keyboardType = value }
|
||||
}
|
||||
|
||||
|
||||
var isValueValid = true {
|
||||
didSet {
|
||||
if isValueValid {
|
||||
@@ -63,26 +63,26 @@ class KeyValueCell: UITableViewCell {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var isStackedHorizontally = false
|
||||
var isStackedVertically = false
|
||||
var contentSizeBasedConstraints = [NSLayoutConstraint]()
|
||||
|
||||
|
||||
var onValueChanged: ((String) -> Void)?
|
||||
var onValueBeingEdited: ((String) -> Void)?
|
||||
|
||||
|
||||
private var textFieldValueOnBeginEditing: String = ""
|
||||
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
|
||||
contentView.addSubview(keyLabel)
|
||||
keyLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
keyLabel.leftAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leftAnchor),
|
||||
keyLabel.topAnchor.constraint(equalToSystemSpacingBelow: contentView.layoutMarginsGuide.topAnchor, multiplier: 0.5)
|
||||
])
|
||||
|
||||
|
||||
valueTextField.delegate = self
|
||||
valueLabelScrollView.addSubview(valueTextField)
|
||||
valueTextField.translatesAutoresizingMaskIntoConstraints = false
|
||||
@@ -96,31 +96,31 @@ class KeyValueCell: UITableViewCell {
|
||||
let expandToFitValueLabelConstraint = NSLayoutConstraint(item: valueTextField, attribute: .width, relatedBy: .equal, toItem: valueLabelScrollView, attribute: .width, multiplier: 1, constant: 0)
|
||||
expandToFitValueLabelConstraint.priority = .defaultLow + 1
|
||||
expandToFitValueLabelConstraint.isActive = true
|
||||
|
||||
|
||||
contentView.addSubview(valueLabelScrollView)
|
||||
|
||||
|
||||
contentView.addSubview(valueLabelScrollView)
|
||||
valueLabelScrollView.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
valueLabelScrollView.rightAnchor.constraint(equalTo: contentView.layoutMarginsGuide.rightAnchor),
|
||||
contentView.layoutMarginsGuide.bottomAnchor.constraint(equalToSystemSpacingBelow: valueLabelScrollView.bottomAnchor, multiplier: 0.5)
|
||||
])
|
||||
|
||||
|
||||
keyLabel.setContentCompressionResistancePriority(.defaultHigh + 1, for: .horizontal)
|
||||
keyLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
||||
valueLabelScrollView.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
||||
|
||||
|
||||
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_:)))
|
||||
addGestureRecognizer(gestureRecognizer)
|
||||
isUserInteractionEnabled = true
|
||||
|
||||
|
||||
configureForContentSize()
|
||||
}
|
||||
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
func configureForContentSize() {
|
||||
var constraints = [NSLayoutConstraint]()
|
||||
if traitCollection.preferredContentSizeCategory.isAccessibilityCategory {
|
||||
@@ -152,13 +152,13 @@ class KeyValueCell: UITableViewCell {
|
||||
contentSizeBasedConstraints = constraints
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@objc func handleTapGesture(_ recognizer: UIGestureRecognizer) {
|
||||
if !copyableGesture {
|
||||
return
|
||||
}
|
||||
guard recognizer.state == .recognized else { return }
|
||||
|
||||
|
||||
if let recognizerView = recognizer.view,
|
||||
let recognizerSuperView = recognizerView.superview, recognizerView.becomeFirstResponder() {
|
||||
let menuController = UIMenuController.shared
|
||||
@@ -166,19 +166,19 @@ class KeyValueCell: UITableViewCell {
|
||||
menuController.setMenuVisible(true, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override var canBecomeFirstResponder: Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
|
||||
return (action == #selector(UIResponderStandardEditActions.copy(_:)))
|
||||
}
|
||||
|
||||
|
||||
override func copy(_ sender: Any?) {
|
||||
UIPasteboard.general.string = valueTextField.text
|
||||
}
|
||||
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
copyableGesture = true
|
||||
@@ -194,18 +194,18 @@ class KeyValueCell: UITableViewCell {
|
||||
}
|
||||
|
||||
extension KeyValueCell: UITextFieldDelegate {
|
||||
|
||||
|
||||
func textFieldDidBeginEditing(_ textField: UITextField) {
|
||||
textFieldValueOnBeginEditing = textField.text ?? ""
|
||||
isValueValid = true
|
||||
}
|
||||
|
||||
|
||||
func textFieldDidEndEditing(_ textField: UITextField) {
|
||||
let isModified = textField.text ?? "" != textFieldValueOnBeginEditing
|
||||
guard isModified else { return }
|
||||
onValueChanged?(textField.text ?? "")
|
||||
}
|
||||
|
||||
|
||||
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
||||
if let onValueBeingEdited = onValueBeingEdited {
|
||||
let modifiedText = ((textField.text ?? "") as NSString).replacingCharacters(in: range, with: string)
|
||||
@@ -213,5 +213,5 @@ extension KeyValueCell: UITextFieldDelegate {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -19,14 +19,14 @@ class SwitchCell: UITableViewCell {
|
||||
textLabel?.textColor = value ? .black : .gray
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var onSwitchToggled: ((Bool) -> Void)?
|
||||
|
||||
|
||||
let switchView = UISwitch()
|
||||
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: .default, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
|
||||
accessoryView = switchView
|
||||
switchView.addTarget(self, action: #selector(switchToggled), for: .valueChanged)
|
||||
}
|
||||
@@ -34,11 +34,11 @@ class SwitchCell: UITableViewCell {
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
@objc func switchToggled() {
|
||||
onSwitchToggled?(switchView.isOn)
|
||||
}
|
||||
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
isEnabled = true
|
||||
|
||||
@@ -4,40 +4,40 @@
|
||||
import UIKit
|
||||
|
||||
class TunnelEditKeyValueCell: KeyValueCell {
|
||||
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
|
||||
keyLabel.textAlignment = .right
|
||||
valueTextField.textAlignment = .left
|
||||
|
||||
|
||||
let widthRatioConstraint = NSLayoutConstraint(item: keyLabel, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 0.4, constant: 0)
|
||||
// In case the key doesn't fit into 0.4 * width,
|
||||
// set a CR priority > the 0.4-constraint's priority.
|
||||
widthRatioConstraint.priority = .defaultHigh + 1
|
||||
widthRatioConstraint.isActive = true
|
||||
}
|
||||
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class TunnelEditEditableKeyValueCell: TunnelEditKeyValueCell {
|
||||
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
|
||||
copyableGesture = false
|
||||
valueTextField.textColor = .black
|
||||
valueTextField.isEnabled = true
|
||||
valueLabelScrollView.isScrollEnabled = false
|
||||
valueTextField.widthAnchor.constraint(equalTo: valueLabelScrollView.widthAnchor).isActive = true
|
||||
}
|
||||
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class TunnelListCell: UITableViewCell {
|
||||
}
|
||||
}
|
||||
var onSwitchToggled: ((Bool) -> Void)?
|
||||
|
||||
|
||||
let nameLabel: UILabel = {
|
||||
let nameLabel = UILabel()
|
||||
nameLabel.font = UIFont.preferredFont(forTextStyle: .body)
|
||||
@@ -27,35 +27,35 @@ class TunnelListCell: UITableViewCell {
|
||||
nameLabel.numberOfLines = 0
|
||||
return nameLabel
|
||||
}()
|
||||
|
||||
|
||||
let busyIndicator: UIActivityIndicatorView = {
|
||||
let busyIndicator = UIActivityIndicatorView(style: .gray)
|
||||
busyIndicator.hidesWhenStopped = true
|
||||
return busyIndicator
|
||||
}()
|
||||
|
||||
|
||||
let statusSwitch = UISwitch()
|
||||
|
||||
|
||||
private var statusObservationToken: AnyObject?
|
||||
private var nameObservationToken: AnyObject?
|
||||
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
|
||||
contentView.addSubview(statusSwitch)
|
||||
statusSwitch.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
statusSwitch.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
|
||||
contentView.rightAnchor.constraint(equalTo: statusSwitch.rightAnchor)
|
||||
])
|
||||
|
||||
|
||||
contentView.addSubview(busyIndicator)
|
||||
busyIndicator.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
busyIndicator.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
|
||||
statusSwitch.leftAnchor.constraint(equalToSystemSpacingAfter: busyIndicator.rightAnchor, multiplier: 1)
|
||||
])
|
||||
|
||||
|
||||
contentView.addSubview(nameLabel)
|
||||
nameLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
nameLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
||||
@@ -67,16 +67,16 @@ class TunnelListCell: UITableViewCell {
|
||||
busyIndicator.leftAnchor.constraint(equalToSystemSpacingAfter: nameLabel.rightAnchor, multiplier: 1),
|
||||
bottomAnchorConstraint
|
||||
])
|
||||
|
||||
|
||||
accessoryType = .disclosureIndicator
|
||||
|
||||
|
||||
statusSwitch.addTarget(self, action: #selector(switchToggled), for: .valueChanged)
|
||||
}
|
||||
|
||||
|
||||
@objc func switchToggled() {
|
||||
onSwitchToggled?(statusSwitch.isOn)
|
||||
}
|
||||
|
||||
|
||||
private func update(from status: TunnelStatus?) {
|
||||
guard let status = status else {
|
||||
reset()
|
||||
@@ -93,17 +93,17 @@ class TunnelListCell: UITableViewCell {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
private func reset() {
|
||||
statusSwitch.isOn = false
|
||||
statusSwitch.isUserInteractionEnabled = false
|
||||
busyIndicator.stopAnimating()
|
||||
}
|
||||
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
reset()
|
||||
|
||||
@@ -58,12 +58,12 @@ class SettingsTableViewController: UITableViewController {
|
||||
override func viewDidLayoutSubviews() {
|
||||
super.viewDidLayoutSubviews()
|
||||
guard let logo = tableView.tableFooterView else { return }
|
||||
|
||||
|
||||
let bottomPadding = max(tableView.layoutMargins.bottom, 10)
|
||||
let fullHeight = max(tableView.contentSize.height, tableView.bounds.size.height - tableView.layoutMargins.top - bottomPadding)
|
||||
|
||||
|
||||
let imageAspectRatio = logo.intrinsicContentSize.width / logo.intrinsicContentSize.height
|
||||
|
||||
|
||||
var height = tableView.estimatedRowHeight * 1.5
|
||||
var width = height * imageAspectRatio
|
||||
let maxWidth = view.bounds.size.width - max(tableView.layoutMargins.left + tableView.layoutMargins.right, 20)
|
||||
@@ -71,11 +71,11 @@ class SettingsTableViewController: UITableViewController {
|
||||
width = maxWidth
|
||||
height = width / imageAspectRatio
|
||||
}
|
||||
|
||||
|
||||
let needsReload = height != logo.frame.height
|
||||
|
||||
|
||||
logo.frame = CGRect(x: (view.bounds.size.width - width) / 2, y: fullHeight - height, width: width, height: height)
|
||||
|
||||
|
||||
if needsReload {
|
||||
tableView.tableFooterView = logo
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class TunnelDetailTableViewController: UITableViewController {
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
deinit {
|
||||
onDemandStatusObservationToken = nil
|
||||
statusObservationToken = nil
|
||||
@@ -166,7 +166,7 @@ extension TunnelDetailTableViewController {
|
||||
|
||||
private func statusCell(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell: SwitchCell = tableView.dequeueReusableCell(for: indexPath)
|
||||
|
||||
|
||||
let statusUpdate: (SwitchCell, TunnelStatus) -> Void = { cell, status in
|
||||
let text: String
|
||||
switch status {
|
||||
@@ -192,13 +192,13 @@ extension TunnelDetailTableViewController {
|
||||
}
|
||||
cell.isEnabled = status == .active || status == .inactive
|
||||
}
|
||||
|
||||
|
||||
statusUpdate(cell, tunnel.status)
|
||||
statusObservationToken = tunnel.observe(\.status) { [weak cell] tunnel, _ in
|
||||
guard let cell = cell else { return }
|
||||
statusUpdate(cell, tunnel.status)
|
||||
}
|
||||
|
||||
|
||||
cell.onSwitchToggled = { [weak self] isOn in
|
||||
guard let self = self else { return }
|
||||
if isOn {
|
||||
|
||||
@@ -17,27 +17,27 @@ class TunnelsListTableViewController: UIViewController {
|
||||
tableView.register(TunnelListCell.self)
|
||||
return tableView
|
||||
}()
|
||||
|
||||
|
||||
let centeredAddButton: BorderedTextButton = {
|
||||
let button = BorderedTextButton()
|
||||
button.title = tr("tunnelsListCenteredAddTunnelButtonTitle")
|
||||
button.isHidden = true
|
||||
return button
|
||||
}()
|
||||
|
||||
|
||||
let busyIndicator: UIActivityIndicatorView = {
|
||||
let busyIndicator = UIActivityIndicatorView(style: .gray)
|
||||
busyIndicator.hidesWhenStopped = true
|
||||
return busyIndicator
|
||||
}()
|
||||
|
||||
|
||||
override func loadView() {
|
||||
view = UIView()
|
||||
view.backgroundColor = .white
|
||||
|
||||
|
||||
tableView.dataSource = self
|
||||
tableView.delegate = self
|
||||
|
||||
|
||||
view.addSubview(tableView)
|
||||
tableView.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
@@ -53,22 +53,22 @@ class TunnelsListTableViewController: UIViewController {
|
||||
busyIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor),
|
||||
busyIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor)
|
||||
])
|
||||
|
||||
|
||||
view.addSubview(centeredAddButton)
|
||||
centeredAddButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
centeredAddButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
|
||||
centeredAddButton.centerYAnchor.constraint(equalTo: view.centerYAnchor)
|
||||
])
|
||||
|
||||
|
||||
centeredAddButton.onTapped = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.addButtonTapped(sender: self.centeredAddButton)
|
||||
}
|
||||
|
||||
|
||||
busyIndicator.startAnimating()
|
||||
}
|
||||
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
@@ -82,7 +82,7 @@ class TunnelsListTableViewController: UIViewController {
|
||||
func setTunnelsManager(tunnelsManager: TunnelsManager) {
|
||||
self.tunnelsManager = tunnelsManager
|
||||
tunnelsManager.tunnelsListDelegate = self
|
||||
|
||||
|
||||
busyIndicator.stopAnimating()
|
||||
tableView.reloadData()
|
||||
centeredAddButton.isHidden = tunnelsManager.numberOfTunnels() > 0
|
||||
@@ -96,7 +96,7 @@ class TunnelsListTableViewController: UIViewController {
|
||||
|
||||
@objc func addButtonTapped(sender: AnyObject) {
|
||||
guard tunnelsManager != nil else { return }
|
||||
|
||||
|
||||
let alert = UIAlertController(title: "", message: tr("addTunnelMenuHeader"), preferredStyle: .actionSheet)
|
||||
let importFileAction = UIAlertAction(title: tr("addTunnelMenuImportFile"), style: .default) { [weak self] _ in
|
||||
self?.presentViewControllerForFileImport()
|
||||
@@ -129,7 +129,7 @@ class TunnelsListTableViewController: UIViewController {
|
||||
|
||||
@objc func settingsButtonTapped(sender: UIBarButtonItem) {
|
||||
guard tunnelsManager != nil else { return }
|
||||
|
||||
|
||||
let settingsVC = SettingsTableViewController(tunnelsManager: tunnelsManager)
|
||||
let settingsNC = UINavigationController(rootViewController: settingsVC)
|
||||
settingsNC.modalPresentationStyle = .formSheet
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
|
||||
protocol WireGuardAppError: Error {
|
||||
typealias AlertText = (title: String, message: String)
|
||||
|
||||
|
||||
var alertText: AlertText { get }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user