subscript(field: InterfaceField) -> String {
get {
if scratchpad.isEmpty {
- // When starting to read a config, setup the scratchpad.
- // The scratchpad shall serve as a cache of what we want to show in the UI.
populateScratchpad()
}
return scratchpad[field] ?? ""
}
set(stringValue) {
if scratchpad.isEmpty {
- // When starting to edit a config, setup the scratchpad and remove the configuration.
- // The scratchpad shall be the sole source of the being-edited configuration.
populateScratchpad()
}
validatedConfiguration = nil
}
func populateScratchpad() {
- // Populate the scratchpad from the configuration object
guard let config = validatedConfiguration else { return }
guard let name = validatedName else { return }
scratchpad[.name] = name
//swiftlint:disable:next cyclomatic_complexity function_body_length
func save() -> SaveResult<(String, InterfaceConfiguration)> {
if let config = validatedConfiguration, let name = validatedName {
- // It's already validated and saved
return .saved((name, config))
}
fieldsWithError.removeAll()
}
return !self[field].isEmpty
}
- // TODO: Cache this to avoid recomputing
}
}
var fieldsWithError = Set<PeerField>()
var validatedConfiguration: PeerConfiguration?
- // For exclude private IPs
private(set) var shouldAllowExcludePrivateIPsControl = false
private(set) var shouldStronglyRecommendDNS = false
private(set) var excludePrivateIPsValue = false
subscript(field: PeerField) -> String {
get {
if scratchpad.isEmpty {
- // When starting to read a config, setup the scratchpad.
- // The scratchpad shall serve as a cache of what we want to show in the UI.
populateScratchpad()
}
return scratchpad[field] ?? ""
}
set(stringValue) {
if scratchpad.isEmpty {
- // When starting to edit a config, setup the scratchpad and remove the configuration.
- // The scratchpad shall be the sole source of the being-edited configuration.
populateScratchpad()
}
validatedConfiguration = nil
}
func populateScratchpad() {
- // Populate the scratchpad from the configuration object
guard let config = validatedConfiguration else { return }
scratchpad[.publicKey] = config.publicKey.base64EncodedString()
if let preSharedKey = config.preSharedKey {
//swiftlint:disable:next cyclomatic_complexity
func save() -> SaveResult<PeerConfiguration> {
if let validatedConfiguration = validatedConfiguration {
- // It's already validated and saved
return .saved(validatedConfiguration)
}
fieldsWithError.removeAll()
}
return (!self[field].isEmpty)
}
- // TODO: Cache this to avoid recomputing
}
static let ipv4DefaultRouteString = "0.0.0.0/0"
modifiedAllowedIPStrings = ipv6Addresses + [TunnelViewModel.PeerData.ipv4DefaultRouteString]
}
scratchpad[.allowedIPs] = modifiedAllowedIPStrings.joined(separator: ", ")
- validatedConfiguration = nil // The configuration has been modified, and needs to be saved
+ validatedConfiguration = nil
excludePrivateIPsValue = isOn
}
}
}
func save() -> SaveResult<TunnelConfiguration> {
- // Attempt to save the interface and all peers, so that all erroring fields are collected
let interfaceSaveResult = interfaceData.save()
- let peerSaveResults = peersData.map { $0.save() }
- // Collate the results
+ let peerSaveResults = peersData.map { $0.save() } // Save all, to help mark erroring fields in red
switch interfaceSaveResult {
case .error(let errorMessage):
return .error(errorMessage)
}
}
-// MARK: Activate on demand
-
extension TunnelViewModel {
static func activateOnDemandOptionText(for activateOnDemandOption: ActivateOnDemandOption) -> String {
switch activateOnDemandOption {
}
}
-// MARK: UIDocumentPickerDelegate
-
extension TunnelsListTableViewController: UIDocumentPickerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
urls.forEach {
}
}
-// MARK: QRScanViewControllerDelegate
-
extension TunnelsListTableViewController: QRScanViewControllerDelegate {
func addScannedQRCode(tunnelConfiguration: TunnelConfiguration, qrScanViewController: QRScanViewController,
completionHandler: (() -> Void)?) {
}
}
-// MARK: UITableViewDataSource
-
extension TunnelsListTableViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
}
-// MARK: UITableViewDelegate
-
extension TunnelsListTableViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let tunnelsManager = tunnelsManager else { return }
}
}
-// MARK: TunnelsManagerDelegate
-
extension TunnelsListTableViewController: TunnelsManagerListDelegate {
func tunnelAdded(at index: Int) {
tableView.insertRows(at: [IndexPath(row: index, section: 0)], with: .automatic)