1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-08-07 03:50:08 +02:00

♻️ Refactor NSMenu structuring

* Added a different way to create menus
* Added NoDomainResultsView (WIP)
This commit is contained in:
2022-08-18 01:59:06 +02:00
parent fcdb4a8993
commit 663082d725
8 changed files with 205 additions and 141 deletions

View File

@ -33,6 +33,8 @@
54FCFD2E276C8D67004CE748 /* HotkeyPreferenceView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 54FCFD2C276C8D67004CE748 /* HotkeyPreferenceView.xib */; };
54FCFD30276C8DA4004CE748 /* HotkeyPreferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54FCFD2F276C8DA4004CE748 /* HotkeyPreferenceView.swift */; };
54FCFD31276C8DA4004CE748 /* HotkeyPreferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54FCFD2F276C8DA4004CE748 /* HotkeyPreferenceView.swift */; };
C40508AF28ADA23D008FAC1F /* NoDomainResultsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40508AE28ADA23D008FAC1F /* NoDomainResultsView.swift */; };
C40508B128ADAB44008FAC1F /* NSMenuItemExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40508B028ADAB44008FAC1F /* NSMenuItemExtension.swift */; };
C405A4D024B9B9140062FAFA /* InternetAccessPolicy.strings in Resources */ = {isa = PBXBuildFile; fileRef = C405A4CE24B9B9130062FAFA /* InternetAccessPolicy.strings */; };
C405A4D124B9B9140062FAFA /* InternetAccessPolicy.plist in Resources */ = {isa = PBXBuildFile; fileRef = C405A4CF24B9B9140062FAFA /* InternetAccessPolicy.plist */; };
C4068CA427B0780A00544CD5 /* CheckboxPreferenceView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C4068CA327B0780A00544CD5 /* CheckboxPreferenceView.xib */; };
@ -314,6 +316,8 @@
54FCFD29276C8AA4004CE748 /* CheckboxPreferenceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxPreferenceView.swift; sourceTree = "<group>"; };
54FCFD2C276C8D67004CE748 /* HotkeyPreferenceView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = HotkeyPreferenceView.xib; sourceTree = "<group>"; };
54FCFD2F276C8DA4004CE748 /* HotkeyPreferenceView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HotkeyPreferenceView.swift; sourceTree = "<group>"; };
C40508AE28ADA23D008FAC1F /* NoDomainResultsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoDomainResultsView.swift; sourceTree = "<group>"; };
C40508B028ADAB44008FAC1F /* NSMenuItemExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSMenuItemExtension.swift; sourceTree = "<group>"; };
C405A4CE24B9B9130062FAFA /* InternetAccessPolicy.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = InternetAccessPolicy.strings; sourceTree = "<group>"; };
C405A4CF24B9B9140062FAFA /* InternetAccessPolicy.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = InternetAccessPolicy.plist; sourceTree = "<group>"; };
C4068CA327B0780A00544CD5 /* CheckboxPreferenceView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CheckboxPreferenceView.xib; sourceTree = "<group>"; };
@ -944,6 +948,7 @@
isa = PBXGroup;
children = (
C44264BF2850BD2A007400F1 /* VersionPopoverView.swift */,
C40508AE28ADA23D008FAC1F /* NoDomainResultsView.swift */,
);
path = Domains;
sourceTree = "<group>";
@ -1120,6 +1125,7 @@
C46FA23E246C358E00944F05 /* StringExtension.swift */,
C48D0C9225CC804200CC7490 /* XibLoadable.swift */,
C42759662627662800093CAE /* NSMenuExtension.swift */,
C40508B028ADAB44008FAC1F /* NSMenuItemExtension.swift */,
C4E0F7EC27BEBDA9007475F2 /* NSWindowExtension.swift */,
C4EB53E628553117006F9937 /* ArrayExtension.swift */,
);
@ -1375,6 +1381,7 @@
C44CCD4027AFE2FC00CE40E5 /* AlertableError.swift in Sources */,
C4188989275FE8CB001EF227 /* Filesystem.swift in Sources */,
C4B6091D2853AB9700C95265 /* ServicesView.swift in Sources */,
C40508B128ADAB44008FAC1F /* NSMenuItemExtension.swift in Sources */,
C4B97B7B275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */,
C4EED88927A48778006D7272 /* InterAppHandler.swift in Sources */,
C40C7F1E2772136000DDDCDC /* PhpEnv.swift in Sources */,
@ -1392,6 +1399,7 @@
C44067F927E2585E0045BD4E /* DomainListTypeCell.swift in Sources */,
54D9E0BA27E4F51E003B9AD9 /* ModifierFlagsExtension.swift in Sources */,
C4C3ED412783497000AB15D8 /* MainMenu+Startup.swift in Sources */,
C40508AF28ADA23D008FAC1F /* NoDomainResultsView.swift in Sources */,
C4D89BC62783C99400A02B68 /* ComposerJson.swift in Sources */,
C46FA23F246C358E00944F05 /* StringExtension.swift in Sources */,
C42E3BF428A9BF5100AFECFC /* Shell+PATH.swift in Sources */,
@ -1687,7 +1695,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 950;
CURRENT_PROJECT_VERSION = 955;
DEBUG = YES;
DEVELOPMENT_TEAM = 8M54J5J787;
ENABLE_HARDENED_RUNTIME = YES;
@ -1697,7 +1705,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 5.5.0;
MARKETING_VERSION = 5.6.0;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1714,7 +1722,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 950;
CURRENT_PROJECT_VERSION = 955;
DEBUG = NO;
DEVELOPMENT_TEAM = 8M54J5J787;
ENABLE_HARDENED_RUNTIME = YES;
@ -1724,7 +1732,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 5.5.0;
MARKETING_VERSION = 5.6.0;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

View File

@ -9,43 +9,28 @@
import Cocoa
extension NSMenu {
open func addItem(_ newItem: NSMenuItem, withKeyModifier modifier: NSEvent.ModifierFlags) {
open func addItem(
_ newItem: NSMenuItem,
withKeyModifier modifier: NSEvent.ModifierFlags
) {
newItem.keyEquivalentModifierMask = modifier
self.addItem(newItem)
}
open func addItems(_ items: [NSMenuItem], target: NSObject? = nil) {
for item in items {
self.addItem(item)
if target != nil {
item.target = target
}
}
}
}
@IBDesignable class LocalizedMenuItem: NSMenuItem {
@IBInspectable
var localizationKey: String? {
@IBInspectable var localizationKey: String? {
didSet {
self.title = localizationKey?.localized ?? self.title
}
}
}
// MARK: - NSMenuItem subclasses
class PhpMenuItem: NSMenuItem {
var version: String = ""
}
class XdebugMenuItem: NSMenuItem {
var mode: String = ""
}
class ExtensionMenuItem: NSMenuItem {
var phpExtension: PhpExtension?
}
class EditorMenuItem: NSMenuItem {
var editor: Application?
}
class PresetMenuItem: NSMenuItem {
var preset: Preset?
}

View File

@ -0,0 +1,45 @@
//
// NSMenuItem.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 18/08/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
//
import Cocoa
extension NSMenuItem {
convenience init(
title: String,
action: Selector? = nil,
keyEquivalent: String = "",
keyModifier: NSEvent.ModifierFlags = [],
tooltip: String = "",
submenu: NSMenu? = nil
) {
self.init(title: title, action: action, keyEquivalent: keyEquivalent)
self.keyEquivalentModifierMask = keyModifier
}
}
// MARK: - NSMenuItem subclasses
class PhpMenuItem: NSMenuItem {
var version: String = ""
}
class XdebugMenuItem: NSMenuItem {
var mode: String = ""
}
class ExtensionMenuItem: NSMenuItem {
var phpExtension: PhpExtension?
}
class EditorMenuItem: NSMenuItem {
var editor: Application?
}
class PresetMenuItem: NSMenuItem {
var preset: Preset?
}

View File

@ -7,6 +7,7 @@
//
import Foundation
import Cocoa
class Xdebug {
@ -26,6 +27,26 @@ class Xdebug {
return value.components(separatedBy: ",").filter { self.modes.contains($0) }
}
public static func asMenuItems() -> [NSMenuItem] {
var items: [NSMenuItem] = []
let activeModes = Self.activeModes
for mode in Self.modes {
let item = XdebugMenuItem(
title: mode,
action: #selector(MainMenu.toggleXdebugMode(sender:)),
keyEquivalent: ""
)
item.state = activeModes.contains(mode) ? .on : .off
item.mode = mode
items.append(item)
}
return items
}
public static var modes: [String] {
return [
"develop",

View File

@ -13,35 +13,37 @@ extension StatusMenu {
// MARK: Remaining Menu Items
func addConfigurationMenuItems() {
self.addItem(HeaderView.asMenuItem(text: "mi_configuration".localized))
self.addItem(
self.addItems([
HeaderView.asMenuItem(text: "mi_configuration".localized),
NSMenuItem(title: "mi_php_config".localized,
action: #selector(MainMenu.openActiveConfigFolder), keyEquivalent: "c")
)
self.addItem(
action: #selector(MainMenu.openActiveConfigFolder),
keyEquivalent: "c"),
NSMenuItem(title: "mi_phpmon_config".localized,
action: #selector(MainMenu.openPhpMonitorConfigurationFile), keyEquivalent: "y")
)
self.addItem(
NSMenuItem(title: "mi_phpinfo".localized, action: #selector(MainMenu.openPhpInfo), keyEquivalent: "i")
)
action: #selector(MainMenu.openPhpMonitorConfigurationFile),
keyEquivalent: "y"),
NSMenuItem(title: "mi_phpinfo".localized,
action: #selector(MainMenu.openPhpInfo),
keyEquivalent: "i")
])
}
func addComposerMenuItems() {
self.addItem(HeaderView.asMenuItem(text: "mi_composer".localized))
self.addItem(
NSMenuItem(title: "mi_global_composer".localized,
action: #selector(MainMenu.openGlobalComposerFolder), keyEquivalent: "g")
)
let composerMenuItem = NSMenuItem(
title: "mi_update_global_composer".localized,
action: PhpEnv.shared.isBusy ? nil : #selector(MainMenu.updateGlobalComposerDependencies),
keyEquivalent: "g"
)
composerMenuItem.keyEquivalentModifierMask = .shift
self.addItem(composerMenuItem)
self.addItems([
HeaderView.asMenuItem(text: "mi_composer".localized),
NSMenuItem(
title: "mi_global_composer".localized,
action: #selector(MainMenu.openGlobalComposerFolder),
keyEquivalent: "g"
),
NSMenuItem(
title: "mi_update_global_composer".localized,
action: PhpEnv.shared.isBusy
? nil
: #selector(MainMenu.updateGlobalComposerDependencies),
keyEquivalent: "g",
keyModifier: [.shift]
)
])
}
func addStatsMenuItem() {
@ -157,100 +159,64 @@ extension StatusMenu {
return
}
self.addItem(NSMenuItem.separator())
let xdebugSwitch = NSMenuItem(
title: "mi_xdebug_mode".localized,
action: nil,
keyEquivalent: ""
)
let xdebugModesMenu = NSMenu()
let activeModes = Xdebug.activeModes
xdebugModesMenu.addItem(HeaderView.asMenuItem(text: "mi_xdebug_available_modes".localized))
for mode in Xdebug.modes {
let item = XdebugMenuItem(
title: mode,
action: #selector(MainMenu.toggleXdebugMode(sender:)),
keyEquivalent: ""
)
item.state = activeModes.contains(mode) ? .on : .off
item.mode = mode
xdebugModesMenu.addItem(item)
}
xdebugModesMenu.addItem(HeaderView.asMenuItem(text: "mi_xdebug_actions".localized))
xdebugModesMenu.addItem(
withTitle: "mi_xdebug_disable_all".localized,
action: #selector(MainMenu.disableAllXdebugModes),
keyEquivalent: ""
let submenu = NSMenu()
submenu.addItems(
[HeaderView.asMenuItem(text: "mi_xdebug_available_modes".localized)]
+ Xdebug.asMenuItems()
+ [HeaderView.asMenuItem(text: "mi_xdebug_actions".localized),
NSMenuItem(title: "mi_xdebug_disable_all".localized,
action: #selector(MainMenu.disableAllXdebugModes))
],
target: MainMenu.shared
)
for item in xdebugModesMenu.items {
item.target = MainMenu.shared
}
let xdebugItem = NSMenuItem(title: "mi_xdebug_mode".localized)
self.setSubmenu(submenu, for: xdebugItem)
self.setSubmenu(xdebugModesMenu, for: xdebugSwitch)
self.addItem(xdebugSwitch)
self.addItems([
NSMenuItem.separator(),
xdebugItem
], target: MainMenu.shared)
}
func addFirstAidAndServicesMenuItems() {
let services = NSMenuItem(title: "mi_other".localized, action: nil, keyEquivalent: "")
let services = NSMenuItem(title: "mi_other".localized)
let servicesMenu = NSMenu()
servicesMenu.addItems([
// FIRST AID
HeaderView.asMenuItem(text: "mi_first_aid".localized),
NSMenuItem(title: "mi_view_onboarding".localized, action: #selector(MainMenu.showWelcomeTour)),
NSMenuItem(title: "mi_fa_php_doctor".localized, action: #selector(MainMenu.openWarnings)),
NSMenuItem.separator(),
NSMenuItem(title: "mi_fix_my_valet".localized(PhpEnv.brewPhpVersion),
action: #selector(MainMenu.fixMyValet),
tooltip: "mi_fix_my_valet_tooltip".localized),
NSMenuItem(title: "mi_fix_brew_permissions".localized(), action: #selector(MainMenu.fixHomebrewPermissions),
tooltip: "mi_fix_brew_permissions_tooltip".localized),
NSMenuItem.separator(),
servicesMenu.addItem(HeaderView.asMenuItem(text: "mi_first_aid".localized))
// SERVICES
HeaderView.asMenuItem(text: "mi_services".localized),
NSMenuItem(title: "mi_restart_dnsmasq".localized, action: #selector(MainMenu.restartDnsMasq),
keyEquivalent: "d"),
NSMenuItem(title: "mi_restart_php_fpm".localized, action: #selector(MainMenu.restartPhpFpm),
keyEquivalent: "p"),
NSMenuItem(title: "mi_restart_nginx".localized, action: #selector(MainMenu.restartNginx),
keyEquivalent: "n"),
NSMenuItem(title: "mi_restart_valet_services".localized, action: #selector(MainMenu.restartValetServices),
keyEquivalent: "s"),
NSMenuItem(title: "mi_stop_valet_services".localized, action: #selector(MainMenu.stopValetServices),
keyEquivalent: "s",
keyModifier: [.command, .shift]),
NSMenuItem.separator(),
servicesMenu.addItem(NSMenuItem(title: "mi_view_onboarding".localized,
action: #selector(MainMenu.showWelcomeTour), keyEquivalent: ""))
servicesMenu.addItem(NSMenuItem(title: "mi_fa_php_doctor".localized,
action: #selector(MainMenu.openWarnings), keyEquivalent: ""))
servicesMenu.addItem(NSMenuItem.separator())
let fixMyValetMenuItem = NSMenuItem(
title: "mi_fix_my_valet".localized(PhpEnv.brewPhpVersion),
action: #selector(MainMenu.fixMyValet), keyEquivalent: ""
)
fixMyValetMenuItem.toolTip = "mi_fix_my_valet_tooltip".localized
servicesMenu.addItem(fixMyValetMenuItem)
let fixHomebrewMenuItem = NSMenuItem(
title: "mi_fix_brew_permissions".localized(),
action: #selector(MainMenu.fixHomebrewPermissions), keyEquivalent: ""
)
fixHomebrewMenuItem.toolTip = "mi_fix_brew_permissions_tooltip".localized
servicesMenu.addItem(fixHomebrewMenuItem)
servicesMenu.addItem(NSMenuItem.separator())
servicesMenu.addItem(HeaderView.asMenuItem(text: "mi_services".localized))
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"))
servicesMenu.addItem(NSMenuItem(title: "mi_restart_valet_services".localized,
action: #selector(MainMenu.restartValetServices), keyEquivalent: "s"))
servicesMenu.addItem(
NSMenuItem(title: "mi_stop_valet_services".localized,
action: #selector(MainMenu.stopValetServices), keyEquivalent: "s"),
withKeyModifier: [.command, .shift]
)
servicesMenu.addItem(NSMenuItem.separator())
servicesMenu.addItem(HeaderView.asMenuItem(text: "mi_manual_actions".localized))
servicesMenu.addItem(
// MANUAL ACTIONS
HeaderView.asMenuItem(text: "mi_manual_actions".localized),
NSMenuItem(title: "mi_php_refresh".localized,
action: #selector(MainMenu.reloadPhpMonitorMenuInForeground), keyEquivalent: "r")
)
for item in servicesMenu.items {
item.target = MainMenu.shared
}
action: #selector(MainMenu.reloadPhpMonitorMenuInForeground),
keyEquivalent: "r")
], target: MainMenu.shared)
self.setSubmenu(servicesMenu, for: services)
self.addItem(services)

View File

@ -0,0 +1,37 @@
//
// NoDomainResults.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 15/08/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
//
import SwiftUI
struct NoDomainResults: View {
@State var searching: Bool = false
var body: some View {
VStack(alignment: .center, spacing: 15) {
Image(systemName: searching ? "magnifyingglass.circle.fill" : "questionmark.circle.fill")
.resizable()
.renderingMode(.template)
.frame(width: 24, height: 24)
VStack(alignment: .center) {
Text(
searching
? "domain_list.no_domains_for_search_query".localizedForSwiftUI
: "domain_list.no_domains".localizedForSwiftUI
)
}
}
.frame(minWidth: 0, maxWidth: .infinity)
.padding(25)
}
}
struct NoDomainResults_Previews: PreviewProvider {
static var previews: some View {
NoDomainResults()
}
}

View File

@ -19,7 +19,6 @@ struct NoWarningsView: View {
VStack(alignment: .center) {
Text("warnings.none".localizedForSwiftUI)
}
}
.frame(minWidth: 0, maxWidth: .infinity)
.padding(25)

View File

@ -100,6 +100,9 @@
"domain_list.title" = "Domains";
"domain_list.subtitle" = "";
"domain_list.no_domains" = "You have not set up any domains or proxies yet.";
"domain_list.no_domains_for_search_query" = "There are no results for your search query.";
"domain_list.tooltips.isolated" = "This domain is isolated and using PHP %@ instead of the globally linked PHP.";
"domain_list.tooltips.checkmark" = "This domain is being served with a version of PHP that is compatible with this requirement (PHP %@). Click on the PHP version next to this checkmark to find out more information about how this requirement was determined.";