mirror of
https://github.com/passepartoutvpn/passepartout-apple.git
synced 2025-02-16 12:52:11 +00:00
Make profile "Connect" item a connection toggle
Requires adding multiple delegates to LightVPNManager.
This commit is contained in:
parent
4d56ed6fca
commit
0fee726951
@ -40,14 +40,14 @@ class DefaultLightVPNManager: LightVPNManager {
|
||||
vpnManager.currentState.vpnStatus.asLightVPNStatus
|
||||
}
|
||||
|
||||
weak var delegate: LightVPNManagerDelegate?
|
||||
private var delegates: [String: LightVPNManagerDelegate] = [:]
|
||||
|
||||
init() {
|
||||
vpnManager.currentState.$isEnabled
|
||||
.removeDuplicates()
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink {
|
||||
self.delegate?.didUpdateState(
|
||||
self.didUpdateState(
|
||||
isEnabled: $0,
|
||||
vpnStatus: self.vpnManager.currentState.vpnStatus.asLightVPNStatus
|
||||
)
|
||||
@ -57,7 +57,7 @@ class DefaultLightVPNManager: LightVPNManager {
|
||||
.removeDuplicates()
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink {
|
||||
self.delegate?.didUpdateState(
|
||||
self.didUpdateState(
|
||||
isEnabled: self.vpnManager.currentState.isEnabled,
|
||||
vpnStatus: $0.asLightVPNStatus
|
||||
)
|
||||
@ -77,6 +77,13 @@ class DefaultLightVPNManager: LightVPNManager {
|
||||
try? await vpnManager.connect(with: profileId, toServer: serverId)
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func disconnect() {
|
||||
Task {
|
||||
await vpnManager.disable()
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func toggle() {
|
||||
@ -95,6 +102,22 @@ class DefaultLightVPNManager: LightVPNManager {
|
||||
await vpnManager.reconnect()
|
||||
}
|
||||
}
|
||||
|
||||
func addDelegate(_ delegate: LightVPNManagerDelegate, withIdentifier identifier: String) {
|
||||
delegates[identifier] = delegate
|
||||
}
|
||||
|
||||
func removeDelegate(withIdentifier identifier: String) {
|
||||
delegates.removeValue(forKey: identifier)
|
||||
}
|
||||
}
|
||||
|
||||
extension DefaultLightVPNManager: LightVPNManagerDelegate {
|
||||
func didUpdateState(isEnabled: Bool, vpnStatus: LightVPNStatus) {
|
||||
delegates.values.forEach {
|
||||
$0.didUpdateState(isEnabled: isEnabled, vpnStatus: vpnStatus)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension VPNStatus {
|
||||
|
@ -46,11 +46,15 @@ public protocol LightVPNManager {
|
||||
|
||||
func connect(with profileId: UUID, to serverId: String)
|
||||
|
||||
func disconnect()
|
||||
|
||||
func toggle()
|
||||
|
||||
func reconnect()
|
||||
|
||||
var delegate: LightVPNManagerDelegate? { get set }
|
||||
func addDelegate(_ delegate: LightVPNManagerDelegate, withIdentifier identifier: String)
|
||||
|
||||
func removeDelegate(withIdentifier identifier: String)
|
||||
}
|
||||
|
||||
@objc
|
||||
|
@ -30,14 +30,40 @@ extension HostProfileItem {
|
||||
let profile: LightProfile
|
||||
|
||||
private let vpnManager: LightVPNManager
|
||||
|
||||
private var didUpdate: ((LightVPNStatus) -> Void)?
|
||||
|
||||
init(_ profile: LightProfile, vpnManager: LightVPNManager) {
|
||||
self.profile = profile
|
||||
self.vpnManager = vpnManager
|
||||
|
||||
vpnManager.addDelegate(self, withIdentifier: profile.id.uuidString)
|
||||
}
|
||||
|
||||
|
||||
deinit {
|
||||
vpnManager.removeDelegate(withIdentifier: profile.id.uuidString)
|
||||
}
|
||||
|
||||
@objc func connectTo() {
|
||||
vpnManager.connect(with: profile.id)
|
||||
}
|
||||
|
||||
@objc func disconnect() {
|
||||
vpnManager.disconnect()
|
||||
}
|
||||
|
||||
func subscribe(_ block: @escaping (LightVPNStatus) -> Void) {
|
||||
didUpdate = block
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension HostProfileItem.ViewModel: LightVPNManagerDelegate {
|
||||
func didUpdateState(isEnabled: Bool, vpnStatus: LightVPNStatus) {
|
||||
guard profile.isActive else {
|
||||
didUpdate?(.disconnected)
|
||||
return
|
||||
}
|
||||
didUpdate?(vpnStatus)
|
||||
}
|
||||
}
|
||||
|
@ -47,16 +47,23 @@ struct HostProfileItem: Item {
|
||||
|
||||
private func submenu() -> NSMenu {
|
||||
let menu = NSMenu()
|
||||
menu.autoenablesItems = false
|
||||
|
||||
let item = NSMenuItem(
|
||||
title: L10n.Global.Strings.connect,
|
||||
action: #selector(viewModel.connectTo),
|
||||
keyEquivalent: ""
|
||||
)
|
||||
item.target = viewModel
|
||||
item.representedObject = viewModel
|
||||
let toggleItem = NSMenuItem()
|
||||
toggleItem.target = viewModel
|
||||
toggleItem.representedObject = viewModel
|
||||
|
||||
menu.addItem(item)
|
||||
viewModel.subscribe {
|
||||
if $0 == .disconnected {
|
||||
toggleItem.title = L10n.Global.Strings.connect
|
||||
toggleItem.action = #selector(viewModel.connectTo)
|
||||
} else {
|
||||
toggleItem.title = L10n.Global.Strings.disconnect
|
||||
toggleItem.action = #selector(viewModel.disconnect)
|
||||
}
|
||||
}
|
||||
|
||||
menu.addItem(toggleItem)
|
||||
return menu
|
||||
}
|
||||
}
|
||||
|
@ -45,10 +45,14 @@ extension PassepartoutMenu {
|
||||
self.profileManager = profileManager
|
||||
self.vpnManager = vpnManager
|
||||
|
||||
vpnManager.delegate = self
|
||||
vpnManager.addDelegate(self, withIdentifier: "PassepartoutMenu")
|
||||
setStatus(vpnManager.vpnStatus)
|
||||
}
|
||||
|
||||
deinit {
|
||||
vpnManager.removeDelegate(withIdentifier: "PassepartoutMenu")
|
||||
}
|
||||
|
||||
func install(systemMenu: SystemMenu) {
|
||||
statusItem.menu = systemMenu.asMenu
|
||||
}
|
||||
|
@ -33,10 +33,18 @@ extension ProviderProfileItem {
|
||||
|
||||
private let vpnManager: LightVPNManager
|
||||
|
||||
private var didUpdate: ((LightVPNStatus) -> Void)?
|
||||
|
||||
init(_ profile: LightProfile, providerManager: LightProviderManager, vpnManager: LightVPNManager) {
|
||||
self.profile = profile
|
||||
self.providerManager = providerManager
|
||||
self.vpnManager = vpnManager
|
||||
|
||||
vpnManager.addDelegate(self, withIdentifier: profile.id.uuidString)
|
||||
}
|
||||
|
||||
deinit {
|
||||
vpnManager.removeDelegate(withIdentifier: profile.id.uuidString)
|
||||
}
|
||||
|
||||
private var providerName: String {
|
||||
@ -55,15 +63,33 @@ extension ProviderProfileItem {
|
||||
}
|
||||
|
||||
func isActiveCategory(_ category: LightProviderCategory) -> Bool {
|
||||
return category.name == profile.providerServer?.categoryName
|
||||
category.name == profile.providerServer?.categoryName
|
||||
}
|
||||
|
||||
func connectTo() {
|
||||
@objc func connectTo() {
|
||||
vpnManager.connect(with: profile.id)
|
||||
}
|
||||
|
||||
@objc func disconnect() {
|
||||
vpnManager.disconnect()
|
||||
}
|
||||
|
||||
func downloadIfNeeded() {
|
||||
providerManager.downloadIfNeeded(providerName, vpnProtocol: vpnProtocol)
|
||||
}
|
||||
|
||||
func subscribe(_ block: @escaping (LightVPNStatus) -> Void) {
|
||||
didUpdate = block
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ProviderProfileItem.ViewModel: LightVPNManagerDelegate {
|
||||
func didUpdateState(isEnabled: Bool, vpnStatus: LightVPNStatus) {
|
||||
guard profile.isActive else {
|
||||
didUpdate?(.disconnected)
|
||||
return
|
||||
}
|
||||
didUpdate?(vpnStatus)
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,8 @@ struct ProviderProfileItem: Item {
|
||||
|
||||
private func submenu() -> NSMenu {
|
||||
let menu = NSMenu()
|
||||
menu.autoenablesItems = false
|
||||
|
||||
let categories = viewModel.categories
|
||||
guard !categories.isEmpty else {
|
||||
let downloadItem = TextItem(L10n.Global.Strings.download) {
|
||||
@ -59,10 +61,21 @@ struct ProviderProfileItem: Item {
|
||||
return menu
|
||||
}
|
||||
|
||||
let connectItem = TextItem(L10n.Global.Strings.connect) {
|
||||
viewModel.connectTo()
|
||||
let toggleItem = NSMenuItem()
|
||||
toggleItem.target = viewModel
|
||||
toggleItem.representedObject = viewModel
|
||||
|
||||
viewModel.subscribe {
|
||||
if $0 == .disconnected {
|
||||
toggleItem.title = L10n.Global.Strings.connect
|
||||
toggleItem.action = #selector(viewModel.connectTo)
|
||||
} else {
|
||||
toggleItem.title = L10n.Global.Strings.disconnect
|
||||
toggleItem.action = #selector(viewModel.disconnect)
|
||||
}
|
||||
}
|
||||
menu.addItem(connectItem.asMenuItem(withParent: menu))
|
||||
|
||||
menu.addItem(toggleItem)
|
||||
menu.addItem(.separator())
|
||||
|
||||
if categories.count > 1 {
|
||||
|
@ -47,7 +47,11 @@ extension VPNItemGroup {
|
||||
self.toggleTitleBlock = toggleTitleBlock
|
||||
self.reconnectTitleBlock = reconnectTitleBlock
|
||||
|
||||
vpnManager.delegate = self
|
||||
vpnManager.addDelegate(self, withIdentifier: "VPNItemGroup")
|
||||
}
|
||||
|
||||
deinit {
|
||||
vpnManager.removeDelegate(withIdentifier: "VPNItemGroup")
|
||||
}
|
||||
|
||||
var toggleTitle: String {
|
||||
|
Loading…
Reference in New Issue
Block a user