Create variable menu items lazily
- Avoid unwrapped optionals - Also, delegate ConnectionService after rebuild() Fix crash on refunded providers.
This commit is contained in:
parent
37fb68c2e1
commit
445249f670
|
@ -67,25 +67,23 @@ class StatusMenu: NSObject {
|
||||||
|
|
||||||
private let menuAllProfiles = NSMenu()
|
private let menuAllProfiles = NSMenu()
|
||||||
|
|
||||||
private var itemSwitchProfile: NSMenuItem?
|
private lazy var itemSwitchProfile = NSMenuItem(title: L10n.App.Menu.SwitchProfile.title, action: nil, keyEquivalent: "")
|
||||||
|
|
||||||
private var itemsAllProfiles: [NSMenuItem] = []
|
private var itemsAllProfiles: [NSMenuItem] = []
|
||||||
|
|
||||||
private var itemProfileName: NSMenuItem?
|
private lazy var itemProfileName = NSMenuItem(title: "", action: nil, keyEquivalent: "")
|
||||||
|
|
||||||
private var itemsProfile: [NSMenuItem] = []
|
private var itemsProfile: [NSMenuItem] = []
|
||||||
|
|
||||||
private var itemPool: NSMenuItem?
|
private lazy var itemPool = NSMenuItem(title: "", action: nil, keyEquivalent: "")
|
||||||
|
|
||||||
private var itemToggleVPN: NSMenuItem?
|
private lazy var itemToggleVPN = NSMenuItem(title: L10n.App.Service.Cells.Vpn.TurnOn.caption, action: nil, keyEquivalent: "")
|
||||||
|
|
||||||
private var itemReconnectVPN: NSMenuItem?
|
private lazy var itemReconnectVPN = NSMenuItem(title: L10n.Core.Service.Cells.Reconnect.caption, action: #selector(reconnectVPN), keyEquivalent: "")
|
||||||
|
|
||||||
private override init() {
|
private override init() {
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
service.delegate = self
|
|
||||||
|
|
||||||
let nc = NotificationCenter.default
|
let nc = NotificationCenter.default
|
||||||
nc.addObserver(self, selector: #selector(vpnDidUpdate), name: VPN.didChangeStatus, object: nil)
|
nc.addObserver(self, selector: #selector(vpnDidUpdate), name: VPN.didChangeStatus, object: nil)
|
||||||
}
|
}
|
||||||
|
@ -103,6 +101,7 @@ class StatusMenu: NSObject {
|
||||||
VPN.shared.prepare {
|
VPN.shared.prepare {
|
||||||
self.rebuild()
|
self.rebuild()
|
||||||
self.statusItem.menu = self.menu
|
self.statusItem.menu = self.menu
|
||||||
|
self.service.delegate = self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,19 +112,17 @@ class StatusMenu: NSObject {
|
||||||
|
|
||||||
let itemShow = NSMenuItem(title: L10n.App.Menu.Show.title, action: #selector(showOrganizer), keyEquivalent: "")
|
let itemShow = NSMenuItem(title: L10n.App.Menu.Show.title, action: #selector(showOrganizer), keyEquivalent: "")
|
||||||
let itemPreferences = NSMenuItem(title: L10n.App.Menu.Preferences.title.asContinuation, action: #selector(showPreferences), keyEquivalent: ",")
|
let itemPreferences = NSMenuItem(title: L10n.App.Menu.Preferences.title.asContinuation, action: #selector(showPreferences), keyEquivalent: ",")
|
||||||
itemSwitchProfile = NSMenuItem(title: L10n.App.Menu.SwitchProfile.title, action: nil, keyEquivalent: "")
|
|
||||||
itemShow.target = self
|
itemShow.target = self
|
||||||
itemPreferences.target = self
|
itemPreferences.target = self
|
||||||
menu.addItem(itemShow)
|
menu.addItem(itemShow)
|
||||||
menu.addItem(itemPreferences)
|
menu.addItem(itemPreferences)
|
||||||
menu.addItem(itemSwitchProfile!)
|
menu.addItem(itemSwitchProfile)
|
||||||
reloadProfiles()
|
reloadProfiles()
|
||||||
menu.addItem(.separator())
|
menu.addItem(.separator())
|
||||||
|
|
||||||
// active profile
|
// active profile
|
||||||
|
|
||||||
itemProfileName = NSMenuItem(title: "", action: nil, keyEquivalent: "")
|
menu.addItem(itemProfileName)
|
||||||
menu.addItem(itemProfileName!)
|
|
||||||
setActiveProfile(service.activeProfile)
|
setActiveProfile(service.activeProfile)
|
||||||
menu.addItem(.separator())
|
menu.addItem(.separator())
|
||||||
|
|
||||||
|
@ -189,7 +186,7 @@ class StatusMenu: NSObject {
|
||||||
menuAllProfiles.addItem(item)
|
menuAllProfiles.addItem(item)
|
||||||
itemsAllProfiles.append(item)
|
itemsAllProfiles.append(item)
|
||||||
}
|
}
|
||||||
menu.setSubmenu(menuAllProfiles, for: itemSwitchProfile!)
|
menu.setSubmenu(menuAllProfiles, for: itemSwitchProfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
func refreshWithCurrentProfile() {
|
func refreshWithCurrentProfile() {
|
||||||
|
@ -197,7 +194,7 @@ class StatusMenu: NSObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setActiveProfile(_ profile: ConnectionProfile?) {
|
func setActiveProfile(_ profile: ConnectionProfile?) {
|
||||||
let startIndex = menu.index(of: itemProfileName!)
|
let startIndex = menu.index(of: itemProfileName)
|
||||||
var i = startIndex + 1
|
var i = startIndex + 1
|
||||||
|
|
||||||
for item in itemsProfile {
|
for item in itemsProfile {
|
||||||
|
@ -206,33 +203,29 @@ class StatusMenu: NSObject {
|
||||||
itemsProfile.removeAll()
|
itemsProfile.removeAll()
|
||||||
|
|
||||||
guard let profile = profile else {
|
guard let profile = profile else {
|
||||||
itemProfileName?.title = L10n.App.Menu.ActiveProfile.Title.none
|
itemProfileName.title = L10n.App.Menu.ActiveProfile.Title.none
|
||||||
// itemProfileName?.image = nil
|
// itemProfileName.image = nil
|
||||||
itemToggleVPN = nil
|
|
||||||
itemReconnectVPN = nil
|
|
||||||
statusItem.button?.image = imageStatusInactive
|
statusItem.button?.image = imageStatusInactive
|
||||||
statusItem.button?.toolTip = nil
|
statusItem.button?.toolTip = nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let profileTitle = service.screenTitle(ProfileKey(profile))
|
let profileTitle = service.screenTitle(ProfileKey(profile))
|
||||||
itemProfileName?.title = profileTitle
|
itemProfileName.title = profileTitle
|
||||||
// itemProfileName?.image = profile.image
|
// itemProfileName.image = profile.image
|
||||||
|
|
||||||
let needsCredentials = service.needsCredentials(for: profile)
|
let needsCredentials = service.needsCredentials(for: profile)
|
||||||
if !needsCredentials {
|
if !needsCredentials {
|
||||||
itemToggleVPN = NSMenuItem(title: L10n.App.Service.Cells.Vpn.TurnOn.caption, action: nil, keyEquivalent: "")
|
itemToggleVPN.indentationLevel = 1
|
||||||
itemReconnectVPN = NSMenuItem(title: L10n.Core.Service.Cells.Reconnect.caption, action: #selector(reconnectVPN), keyEquivalent: "")
|
itemReconnectVPN.indentationLevel = 1
|
||||||
itemToggleVPN?.indentationLevel = 1
|
itemToggleVPN.target = self
|
||||||
itemReconnectVPN?.indentationLevel = 1
|
itemReconnectVPN.target = self
|
||||||
itemToggleVPN?.target = self
|
menu.insertItem(itemToggleVPN, at: i)
|
||||||
itemReconnectVPN?.target = self
|
|
||||||
menu.insertItem(itemToggleVPN!, at: i)
|
|
||||||
i += 1
|
i += 1
|
||||||
menu.insertItem(itemReconnectVPN!, at: i)
|
menu.insertItem(itemReconnectVPN, at: i)
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
itemsProfile.append(itemToggleVPN!)
|
itemsProfile.append(itemToggleVPN)
|
||||||
itemsProfile.append(itemReconnectVPN!)
|
itemsProfile.append(itemReconnectVPN)
|
||||||
} else {
|
} else {
|
||||||
let itemMissingCredentials = NSMenuItem(title: L10n.App.Menu.ActiveProfile.Messages.missingCredentials, action: nil, keyEquivalent: "")
|
let itemMissingCredentials = NSMenuItem(title: L10n.App.Menu.ActiveProfile.Messages.missingCredentials, action: nil, keyEquivalent: "")
|
||||||
itemMissingCredentials.indentationLevel = 1
|
itemMissingCredentials.indentationLevel = 1
|
||||||
|
@ -296,10 +289,10 @@ class StatusMenu: NSObject {
|
||||||
// guard poolDescription = providerProfile.pool?.localizedId else {
|
// guard poolDescription = providerProfile.pool?.localizedId else {
|
||||||
// fatalError("No pool selected?")
|
// fatalError("No pool selected?")
|
||||||
// }
|
// }
|
||||||
itemPool = NSMenuItem(title: providerProfile.pool?.localizedId ?? "", action: nil, keyEquivalent: "")
|
itemPool.title = providerProfile.pool?.localizedId ?? ""
|
||||||
menu.insertItem(itemPool!, at: i)
|
menu.insertItem(itemPool, at: i)
|
||||||
i += 1
|
i += 1
|
||||||
itemsProfile.append(itemPool!)
|
itemsProfile.append(itemPool)
|
||||||
|
|
||||||
let infrastructure = providerProfile.infrastructure
|
let infrastructure = providerProfile.infrastructure
|
||||||
for category in infrastructure.categories {
|
for category in infrastructure.categories {
|
||||||
|
@ -540,11 +533,11 @@ class StatusMenu: NSObject {
|
||||||
|
|
||||||
private func updateUIWithVPNStatus() {
|
private func updateUIWithVPNStatus() {
|
||||||
if vpn.isEnabled {
|
if vpn.isEnabled {
|
||||||
itemToggleVPN?.title = L10n.App.Service.Cells.Vpn.TurnOff.caption
|
itemToggleVPN.title = L10n.App.Service.Cells.Vpn.TurnOff.caption
|
||||||
itemToggleVPN?.action = #selector(disableVPN)
|
itemToggleVPN.action = #selector(disableVPN)
|
||||||
} else {
|
} else {
|
||||||
itemToggleVPN?.title = L10n.App.Service.Cells.Vpn.TurnOn.caption
|
itemToggleVPN.title = L10n.App.Service.Cells.Vpn.TurnOn.caption
|
||||||
itemToggleVPN?.action = #selector(enableVPN)
|
itemToggleVPN.action = #selector(enableVPN)
|
||||||
}
|
}
|
||||||
if let profile = service.activeProfile {
|
if let profile = service.activeProfile {
|
||||||
let profileTitle = service.screenTitle(ProfileKey(profile))
|
let profileTitle = service.screenTitle(ProfileKey(profile))
|
||||||
|
@ -615,7 +608,7 @@ extension StatusMenu: ConnectionServiceDelegate {
|
||||||
guard let providerProfile = profile as? ProviderConnectionProfile else {
|
guard let providerProfile = profile as? ProviderConnectionProfile else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
itemPool?.title = providerProfile.pool?.localizedId ?? ""
|
itemPool.title = providerProfile.pool?.localizedId ?? ""
|
||||||
|
|
||||||
NotificationCenter.default.post(name: StatusMenu.didUpdateProfile, object: profile)
|
NotificationCenter.default.post(name: StatusMenu.didUpdateProfile, object: profile)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue