mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2026-03-26 06:00:07 +01:00
♻️ Rework interapp handling, ensure preferences UI observes changes
This commit is contained in:
@@ -11,5 +11,6 @@ import Foundation
|
||||
class Events {
|
||||
|
||||
static let ServicesUpdated = Notification.Name("ServicesUpdated")
|
||||
static let PreferencesUpdated = Notification.Name("PreferencesUpdated")
|
||||
|
||||
}
|
||||
|
||||
@@ -105,6 +105,9 @@ class App {
|
||||
/** The window controller of the PHP extension manager window. */
|
||||
var phpExtensionManagerWindowController: PhpExtensionManagerWindowController?
|
||||
|
||||
/** URL that was received before the app finished booting. Will be processed once the startup procedure completes. */
|
||||
var deferredURL: URL?
|
||||
|
||||
/** List of detected (installed) applications that PHP Monitor can work with. */
|
||||
var detectedApplications: [Application] = []
|
||||
|
||||
|
||||
@@ -17,17 +17,40 @@ extension AppDelegate {
|
||||
application URL. You can use the `phpmon://` protocol to communicate with the app.
|
||||
|
||||
At this time you can trigger the site list using Alfred (or some other application)
|
||||
by opening the following URL: `phpmon://list`.
|
||||
by opening the following URL: `phpmon://list`. Various other commands are also made
|
||||
available via the `InterApp` class, which is where all commands and their different
|
||||
interactions are declared.
|
||||
|
||||
Please note that PHP Monitor needs to be running in the background for this to work.
|
||||
Please note that PHP Monitor needs to be running in the background for this to work,
|
||||
or the app will launch and the command will be deferred until the app is ready.
|
||||
*/
|
||||
@MainActor func application(_ application: NSApplication, open urls: [URL]) {
|
||||
guard Startup.hasFinishedBooting else {
|
||||
return deferURLs(urls)
|
||||
}
|
||||
|
||||
handleURLs(urls)
|
||||
}
|
||||
|
||||
@MainActor func deferURLs(_ urls: [URL]) {
|
||||
Log.info("App has not finished booting, deferring phpmon:// command...")
|
||||
App.shared.deferredURL = urls.first
|
||||
}
|
||||
|
||||
@MainActor func handleURLs(_ urls: [URL]) {
|
||||
if !Preferences.isEnabled(.allowProtocolForIntegrations) {
|
||||
if UserDefaults.standard.bool(forKey: PersistentAppState.didPromptForIntegrations.rawValue) {
|
||||
|
||||
// First, we'll check if we already prompted for integrations.
|
||||
// If we have, we will not respond to the commands at all.
|
||||
if UserDefaults.standard.bool(
|
||||
forKey: PersistentAppState.didPromptForIntegrations.rawValue
|
||||
) {
|
||||
Log.info("Acting on commands via phpmon:// has been disabled.")
|
||||
return
|
||||
}
|
||||
|
||||
// However, if that isn't the case, we will prompt the user about integrations,
|
||||
// which will give the user a chance to approve the command regardless.
|
||||
Log.info("Acting on commands via phpmon:// has been disabled. Prompting user...")
|
||||
if !promptToEnableIntegrations() {
|
||||
return
|
||||
@@ -58,7 +81,7 @@ extension AppDelegate {
|
||||
return false
|
||||
}
|
||||
|
||||
Preferences.update(.allowProtocolForIntegrations, value: true)
|
||||
Preferences.update(.allowProtocolForIntegrations, value: true, notify: true)
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -124,6 +124,12 @@ extension Startup {
|
||||
Startup.hasFinishedBooting = true
|
||||
Log.info("PHP Monitor is ready to serve!")
|
||||
|
||||
// Process the last URL that arrived during startup
|
||||
if let url = App.shared.deferredURL {
|
||||
AppDelegate.instance.handleURLs([url])
|
||||
App.shared.deferredURL = nil
|
||||
}
|
||||
|
||||
// Enable the main menu item
|
||||
MainMenu.shared.statusItem.button?.isEnabled = true
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ extension Valet {
|
||||
)
|
||||
.withPrimary(text: "generic.ok".localized)
|
||||
.withTertiary(text: "alert.do_not_tell_again".localized, action: { alert in
|
||||
Preferences.update(.warnAboutNonStandardTLD, value: false)
|
||||
Preferences.update(.warnAboutNonStandardTLD, value: false, notify: true)
|
||||
alert.close(with: .alertThirdButtonReturn)
|
||||
})
|
||||
.show(urgency: .urgentRequestAttention)
|
||||
|
||||
@@ -168,7 +168,7 @@ class Preferences {
|
||||
})
|
||||
}
|
||||
|
||||
static func update(_ preference: PreferenceName, value: Any?) {
|
||||
static func update(_ preference: PreferenceName, value: Any?, notify: Bool = false) {
|
||||
if value == nil {
|
||||
UserDefaults.standard.removeObject(forKey: preference.rawValue)
|
||||
} else {
|
||||
@@ -178,5 +178,9 @@ class Preferences {
|
||||
|
||||
// Update the preferences cache in memory!
|
||||
App.shared.container.preferences.cachedPreferences = Preferences.cache()
|
||||
|
||||
if notify {
|
||||
NotificationCenter.default.post(name: Events.PreferencesUpdated, object: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,15 @@ class CheckboxPreferenceBehavior: CheckboxPreferenceViewBehavior {
|
||||
self.preference = preference
|
||||
self.button = button
|
||||
self.button.state = Preferences.isEnabled(self.preference) ? .on : .off
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
self, selector: #selector(refreshState),
|
||||
name: Events.PreferencesUpdated, object: nil
|
||||
)
|
||||
}
|
||||
|
||||
@objc func refreshState() {
|
||||
self.button.state = Preferences.isEnabled(self.preference) ? .on : .off
|
||||
}
|
||||
|
||||
public func toggled(checked: Bool) {
|
||||
|
||||
@@ -73,9 +73,23 @@ class SelectPreferenceView: NSView, XibLoadable {
|
||||
view.preference = preference
|
||||
view.action = action
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
view, selector: #selector(view.refreshState),
|
||||
name: Events.PreferencesUpdated, object: nil
|
||||
)
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
@objc func refreshState() {
|
||||
let value = Preferences.preferences[preference] as! String
|
||||
self.options.enumerated().forEach { option in
|
||||
if option.element.value == value {
|
||||
self.popupButton.selectItem(at: option.offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func valueChanged(_ sender: Any) {
|
||||
let index = self.popupButton.indexOfSelectedItem
|
||||
Preferences.update(self.preference, value: self.options[index].value)
|
||||
|
||||
@@ -954,8 +954,8 @@ PHP Monitor will tell Valet to unsecure and re-secure all expired domains for yo
|
||||
|
||||
// THIRD-PARTY INTEGRATIONS
|
||||
|
||||
"alert.enable_integrations.title" = "An external application is trying to communicate with PHP Monitor";
|
||||
"alert.enable_integrations.subtitle" = "Do you want to allow third-party integrations (like Alfred or Raycast) to control PHP Monitor via the `phpmon://` protocol?\n\nThis notice appears because PHP Monitor just received an external command. If you triggered this intentionally, using a third-party app like Alfred or Raycast, it is safe to allow this.\n\nYou can change this setting later in Preferences.";
|
||||
"alert.enable_integrations.desc" = "If you did not trigger this via Alfred or Raycast, there may be another application trying to control PHP Monitor. In that case, I recommend keeping this integration turned off, unless you are fine with another third party app controlling PHP Monitor for you, which could present a security risk.";
|
||||
"alert.enable_integrations.ok" = "Allow";
|
||||
"alert.enable_integrations.title" = "An external application is trying to communicate with PHP Monitor. Do you want third-party applications to be able to communicate with PHP Monitor?";
|
||||
"alert.enable_integrations.subtitle" = "This notice appears because PHP Monitor just received an external command, and this feature is disabled by default. If you triggered this intentionally, using a third-party app like Alfred or Raycast, it is normally safe to allow this.\n\nYou can change this setting later in Preferences, you will be asked this question only once.";
|
||||
"alert.enable_integrations.desc" = "If you did not trigger this via Alfred or Raycast, there may be another application trying to control PHP Monitor.\n\nIn such a case, I recommend keeping this integration turned off, unless you are fine with another third party app controlling PHP Monitor for you, which could present a potential security risk.";
|
||||
"alert.enable_integrations.ok" = "Allow Integrations";
|
||||
"alert.enable_integrations.cancel" = "Don't Allow";
|
||||
|
||||
Reference in New Issue
Block a user