on-demand: Introducing ActivateOnDemandViewModel

Signed-off-by: Roopesh Chander <roop@roopc.net>
This commit is contained in:
Roopesh Chander 2019-02-27 13:25:53 +05:30 committed by Jason A. Donenfeld
parent 5d757982ba
commit 7a450089c0
3 changed files with 145 additions and 0 deletions

View File

@ -77,6 +77,8 @@
6F7F7E5F21C7D74B00527607 /* TunnelErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7F7E5E21C7D74B00527607 /* TunnelErrors.swift */; };
6F89E17A21EDEB0E00C97BB9 /* StatusItemController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F89E17921EDEB0E00C97BB9 /* StatusItemController.swift */; };
6F89E17C21F090CC00C97BB9 /* TunnelsTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F89E17B21F090CC00C97BB9 /* TunnelsTracker.swift */; };
6F8F0D7122258153000E8335 /* ActivateOnDemandViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F8F0D7022258153000E8335 /* ActivateOnDemandViewModel.swift */; };
6F8F0D7222258153000E8335 /* ActivateOnDemandViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F8F0D7022258153000E8335 /* ActivateOnDemandViewModel.swift */; };
6F919EC3218A2AE90023B400 /* ErrorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */; };
6F919ED9218C65C50023B400 /* wireguard_doc_logo_22x29.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F919ED5218C65C50023B400 /* wireguard_doc_logo_22x29.png */; };
6F919EDA218C65C50023B400 /* wireguard_doc_logo_44x58.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F919ED6218C65C50023B400 /* wireguard_doc_logo_44x58.png */; };
@ -294,6 +296,7 @@
6F7F7E5E21C7D74B00527607 /* TunnelErrors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelErrors.swift; sourceTree = "<group>"; };
6F89E17921EDEB0E00C97BB9 /* StatusItemController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusItemController.swift; sourceTree = "<group>"; };
6F89E17B21F090CC00C97BB9 /* TunnelsTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelsTracker.swift; sourceTree = "<group>"; };
6F8F0D7022258153000E8335 /* ActivateOnDemandViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivateOnDemandViewModel.swift; sourceTree = "<group>"; };
6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorPresenter.swift; sourceTree = "<group>"; };
6F919ED5218C65C50023B400 /* wireguard_doc_logo_22x29.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wireguard_doc_logo_22x29.png; sourceTree = "<group>"; };
6F919ED6218C65C50023B400 /* wireguard_doc_logo_44x58.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wireguard_doc_logo_44x58.png; sourceTree = "<group>"; };
@ -474,6 +477,7 @@
6FB1BD5E21D2607A00A991BF /* macOS */,
6F7774DE217181B1006A79B3 /* iOS */,
6F628C3C217F09E9003482A3 /* TunnelViewModel.swift */,
6F8F0D7022258153000E8335 /* ActivateOnDemandViewModel.swift */,
6FBA103D21D6B6D70051C35F /* TunnelImporter.swift */,
6FBA103A21D6B4280051C35F /* ErrorPresenterProtocol.swift */,
6B62E45E220A6FA900EF34A6 /* PrivateDataConfirmation.swift */,
@ -1132,6 +1136,7 @@
files = (
6FBA101521D613F90051C35F /* Application.swift in Sources */,
6FB1BDCC21D50F5300A991BF /* TunnelsManager.swift in Sources */,
6F8F0D7222258153000E8335 /* ActivateOnDemandViewModel.swift in Sources */,
6FB1BDCD21D50F5300A991BF /* ActivateOnDemandSetting.swift in Sources */,
6FB1BDCE21D50F5300A991BF /* TunnelStatus.swift in Sources */,
6FB1BDD021D50F5300A991BF /* TunnelErrors.swift in Sources */,
@ -1232,6 +1237,7 @@
5F45417D21C1B23600994C13 /* UITableViewCell+Reuse.swift in Sources */,
5F45419221C2D55800994C13 /* CheckmarkCell.swift in Sources */,
6FE254FF219C60290028284D /* ZipExporter.swift in Sources */,
6F8F0D7122258153000E8335 /* ActivateOnDemandViewModel.swift in Sources */,
6B586C53220CBA6D00427C51 /* Data+KeyEncoding.swift in Sources */,
6F693A562179E556008551C1 /* Endpoint.swift in Sources */,
6FDEF7E62185EFB200D8FBF6 /* QRScanViewController.swift in Sources */,

View File

@ -81,6 +81,17 @@
"tunnelSectionTitleOnDemand" = "On-Demand Activation";
"tunnelOnDemandCellular" = "Cellular";
"tunnelOnDemandEthernet" = "Ethernet";
"tunnelOnDemandWiFi" = "Wi-Fi";
"tunnelOnDemandSSIDDescription" = "Selected SSIDs";
"tunnelOnDemandSSIDescriptionMac" = "SSIDs";
"tunnelOnDemandSSIDEdit" = "Select SSIDs";
"tunnelOnDemandAnySSID" = "Any SSID";
"tunnelOnDemandOnlySelectedSSIDs" = "Only selected SSIDs";
"tunnelOnDemandExceptSelectedSSIDs" = "Except selected SSIDs";
"tunnelOnDemandKey" = "Activate on demand";
"tunnelOnDemandOptionOff" = "Off";
"tunnelOnDemandOptionWiFiOnly" = "Wi-Fi only";

View File

@ -0,0 +1,128 @@
// SPDX-License-Identifier: MIT
// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
import Foundation
class ActivateOnDemandViewModel {
enum OnDemandField {
case nonWiFiInterface
case wiFiInterface
case ssidDescription
case ssidEdit
var localizedUIString: String {
switch self {
case .nonWiFiInterface:
#if os(iOS)
return tr("tunnelOnDemandCellular")
#elseif os(macOS)
return tr("tunnelOnDemandEthernet")
#else
#error("Unimplemented")
#endif
case .wiFiInterface: return tr("tunnelOnDemandWiFi")
case .ssidDescription: return tr("tunnelOnDemandSSIDDescription")
case .ssidEdit: return tr("tunnelOnDemandSSIDEdit")
}
}
}
enum OnDemandSSIDOption {
case anySSID
case onlySpecificSSIDs
case exceptSpecificSSIDs
var localizedUIString: String {
switch self {
case .anySSID: return tr("tunnelOnDemandAnySSID")
case .onlySpecificSSIDs: return tr("tunnelOnDemandOnlySelectedSSIDs")
case .exceptSpecificSSIDs: return tr("tunnelOnDemandExceptSelectedSSIDs")
}
}
}
var isNonWiFiInterfaceEnabled = false
var isWiFiInterfaceEnabled = false
var selectedSSIDs = [String]()
var ssidOption: OnDemandSSIDOption = .anySSID
}
extension ActivateOnDemandViewModel {
convenience init(from option: ActivateOnDemandOption) {
self.init()
switch option {
case .none:
break
case .wiFiInterfaceOnly(let onDemandSSIDOption):
isWiFiInterfaceEnabled = true
(ssidOption, selectedSSIDs) = ssidViewModel(from: onDemandSSIDOption)
case .nonWiFiInterfaceOnly:
isNonWiFiInterfaceEnabled = true
case .anyInterface(let onDemandSSIDOption):
isWiFiInterfaceEnabled = true
isNonWiFiInterfaceEnabled = true
(ssidOption, selectedSSIDs) = ssidViewModel(from: onDemandSSIDOption)
}
}
func toOnDemandOption() -> ActivateOnDemandOption {
switch (isWiFiInterfaceEnabled, isNonWiFiInterfaceEnabled) {
case (false, false):
return .none
case (false, true):
return .nonWiFiInterfaceOnly
case (true, false):
return .wiFiInterfaceOnly(toSSIDOption())
case (true, true):
return .anyInterface(toSSIDOption())
}
}
}
extension ActivateOnDemandViewModel {
func isEnabled(field: OnDemandField) -> Bool {
switch field {
case .nonWiFiInterface:
return isNonWiFiInterfaceEnabled
case .wiFiInterface:
return isWiFiInterfaceEnabled
default:
return false
}
}
func setEnabled(field: OnDemandField, isEnabled: Bool) {
switch field {
case .nonWiFiInterface:
isNonWiFiInterfaceEnabled = isEnabled
case .wiFiInterface:
isWiFiInterfaceEnabled = isEnabled
default:
break
}
}
}
private extension ActivateOnDemandViewModel {
func ssidViewModel(from ssidOption: ActivateOnDemandSSIDOption) -> (OnDemandSSIDOption, [String]) {
switch ssidOption {
case .anySSID:
return (.anySSID, [])
case .onlySpecificSSIDs(let ssids):
return (.onlySpecificSSIDs, ssids)
case .exceptSpecificSSIDs(let ssids):
return (.exceptSpecificSSIDs, ssids)
}
}
func toSSIDOption() -> ActivateOnDemandSSIDOption {
switch ssidOption {
case .anySSID:
return .anySSID
case .onlySpecificSSIDs:
return .onlySpecificSSIDs(selectedSSIDs)
case .exceptSpecificSSIDs:
return .exceptSpecificSSIDs(selectedSSIDs)
}
}
}