diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index a6967db..616592a 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -338,6 +338,7 @@ C464ADAA275A7A25003FCD53 /* SiteList */, 5420395726135DB800FB00FA /* Preferences */, C44C198F276E3A380072762D /* Progress */, + C4C8E81D276F5686003AC782 /* Watcher */, C4811D2822D70D9C00B5F6B3 /* Helpers */, C4F8C0A222D4F100002EFE61 /* Extensions */, ); @@ -427,15 +428,22 @@ C436039F275E67610028EFC6 /* AppDelegate+Notifications.swift */, C4811D2322D70A4700B5F6B3 /* App.swift */, C4B97B77275CF1B5003F3378 /* App+ActivationPolicy.swift */, - C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */, C4B97B7A275CF20A003F3378 /* App+GlobalHotkey.swift */, - C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */, C4D8016522B1584700C6DA1B /* Startup.swift */, C41C1B4C22B0215A00E7CF16 /* Actions.swift */, ); path = Core; sourceTree = ""; }; + C4C8E81D276F5686003AC782 /* Watcher */ = { + isa = PBXGroup; + children = ( + C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */, + C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */, + ); + path = Watcher; + sourceTree = ""; + }; C4F7807A25D7F84B000DBC97 /* phpmon-tests */ = { isa = PBXGroup; children = ( diff --git a/phpmon/Domain/Menu/StatusMenu.swift b/phpmon/Domain/Menu/StatusMenu.swift index 5a10369..609f2cc 100644 --- a/phpmon/Domain/Menu/StatusMenu.swift +++ b/phpmon/Domain/Menu/StatusMenu.swift @@ -39,9 +39,11 @@ class StatusMenu : NSMenu { } func addServicesMenuItems() { - let services = NSMenuItem(title: "mi_manage_services".localized, action: nil, keyEquivalent: "") + let services = NSMenuItem(title: "mi_toolkit".localized, action: nil, keyEquivalent: "") let servicesMenu = NSMenu() + servicesMenu.addItem(NSMenuItem(title: "mi_help".localized, action: nil, keyEquivalent: "")) + if !App.shared.availablePhpVersions.contains(App.shared.brewPhpVersion) { servicesMenu.addItem(NSMenuItem( title: "mi_force_load_latest_unavailable".localized(App.shared.brewPhpVersion), @@ -53,6 +55,8 @@ class StatusMenu : NSMenu { action: #selector(MainMenu.forceRestartLatestPhp), keyEquivalent: "f")) } + servicesMenu.addItem(NSMenuItem(title: "mi_services".localized, action: nil, keyEquivalent: "")) + servicesMenu.addItem(NSMenuItem(title: "mi_restart_dnsmasq".localized, action: #selector(MainMenu.restartDnsMasq), keyEquivalent: "d")) servicesMenu.addItem(NSMenuItem(title: "mi_restart_php_fpm".localized, action: #selector(MainMenu.restartPhpFpm), keyEquivalent: "p")) servicesMenu.addItem(NSMenuItem(title: "mi_restart_nginx".localized, action: #selector(MainMenu.restartNginx), keyEquivalent: "n")) @@ -63,10 +67,16 @@ class StatusMenu : NSMenu { servicesMenu.addItem(NSMenuItem(title: "mi_restart_all_services".localized, action: #selector(MainMenu.restartAllServices), keyEquivalent: "s")) + servicesMenu.addItem(NSMenuItem(title: "mi_manual_actions".localized, action: nil, keyEquivalent: "")) + + servicesMenu.addItem(NSMenuItem(title: "mi_php_refresh".localized, action: #selector(MainMenu.reloadPhpMonitorMenu), keyEquivalent: "r")) + for item in servicesMenu.items { item.target = MainMenu.shared } + + self.setSubmenu(servicesMenu, for: services) self.addItem(services) } @@ -124,10 +134,6 @@ class StatusMenu : NSMenu { self.addItem(NSMenuItem.separator()) - self.addItem(NSMenuItem(title: "mi_php_refresh".localized, action: #selector(MainMenu.reloadPhpMonitorMenu), keyEquivalent: "r")) - - self.addItem(NSMenuItem.separator()) - self.addServicesMenuItems() } @@ -189,4 +195,4 @@ class ExtensionMenuItem: NSMenuItem { class EditorMenuItem: NSMenuItem { var editor: Application? = nil -} \ No newline at end of file +} diff --git a/phpmon/Domain/Core/App+ConfigWatch.swift b/phpmon/Domain/Watcher/App+ConfigWatch.swift similarity index 71% rename from phpmon/Domain/Core/App+ConfigWatch.swift rename to phpmon/Domain/Watcher/App+ConfigWatch.swift index 33e11bd..c550f8f 100644 --- a/phpmon/Domain/Core/App+ConfigWatch.swift +++ b/phpmon/Domain/Watcher/App+ConfigWatch.swift @@ -15,9 +15,15 @@ extension App { self.watcher = PhpConfigWatcher(for: url) self.watcher.didChange = { url in - // TODO: Make sure this is debounced, because a single process may update the config file many times; this occurs when installing Xdebug, for example print("Something has changed in: \(url)") - MainMenu.shared.reloadPhpMonitorMenuInBackground() + + // Check if the watcher has last updated the menu less than 0.75s ago + let distance = self.watcher.lastUpdate?.distance(to: Date().timeIntervalSince1970) + if distance == nil || distance != nil && distance! > 0.75 { + print("Refreshing menu...") + MainMenu.shared.reloadPhpMonitorMenuInBackground() + self.watcher.lastUpdate = Date().timeIntervalSince1970 + } } } diff --git a/phpmon/Domain/Core/PhpConfigWatcher.swift b/phpmon/Domain/Watcher/PhpConfigWatcher.swift similarity index 98% rename from phpmon/Domain/Core/PhpConfigWatcher.swift rename to phpmon/Domain/Watcher/PhpConfigWatcher.swift index 5312d92..0d6608e 100644 --- a/phpmon/Domain/Core/PhpConfigWatcher.swift +++ b/phpmon/Domain/Watcher/PhpConfigWatcher.swift @@ -16,6 +16,8 @@ class PhpConfigWatcher { var didChange: ((URL) -> Void)? + var lastUpdate: TimeInterval? = nil + var watchers: [FSWatcher] = [] init(for url: URL) { diff --git a/phpmon/Localizable.strings b/phpmon/Localizable.strings index 7a3f73f..7e95f30 100644 --- a/phpmon/Localizable.strings +++ b/phpmon/Localizable.strings @@ -34,6 +34,10 @@ "mi_memory_limit" = "Memory Limit"; "mi_post_max_size" = "Max POST"; "mi_upload_max_filesize" = "Max Upload"; +"mi_manual_actions" = "Manual Actions"; +"mi_services" = "Services"; +"mi_help" = "First Aid"; +"mi_toolkit" = "Toolkit"; "mi_composer" = "Composer"; "mi_valet_config" = "Locate Valet folder (.config/valet)";