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

Updated UI for presets

This commit is contained in:
2022-05-30 19:34:10 +02:00
parent 19aa804cbb
commit bbebe78997
8 changed files with 322 additions and 226 deletions

View File

@ -88,6 +88,8 @@
C42337A3281F19F000459A48 /* Xdebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42337A2281F19F000459A48 /* Xdebug.swift */; };
C42759672627662800093CAE /* NSMenuExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42759662627662800093CAE /* NSMenuExtension.swift */; };
C42759682627662800093CAE /* NSMenuExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42759662627662800093CAE /* NSMenuExtension.swift */; };
C42800AA28452AA10099C999 /* StatusMenu+Items.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42800A928452AA10099C999 /* StatusMenu+Items.swift */; };
C42800AB28452AA50099C999 /* StatusMenu+Items.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42800A928452AA10099C999 /* StatusMenu+Items.swift */; };
C42C49DB27C2806F0074ABAC /* MainMenu+FixMyValet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */; };
C42CFB1627DFDE7900862737 /* nginx-site.test in Resources */ = {isa = PBXBuildFile; fileRef = C42CFB1527DFDE7900862737 /* nginx-site.test */; };
C42CFB1827DFDFDC00862737 /* nginx-site-isolated.test in Resources */ = {isa = PBXBuildFile; fileRef = C42CFB1727DFDFDC00862737 /* nginx-site-isolated.test */; };
@ -334,6 +336,7 @@
C4232EE42612526500158FC6 /* Credits.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = Credits.html; sourceTree = "<group>"; };
C42337A2281F19F000459A48 /* Xdebug.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Xdebug.swift; sourceTree = "<group>"; };
C42759662627662800093CAE /* NSMenuExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSMenuExtension.swift; sourceTree = "<group>"; };
C42800A928452AA10099C999 /* StatusMenu+Items.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusMenu+Items.swift"; sourceTree = "<group>"; };
C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+FixMyValet.swift"; sourceTree = "<group>"; };
C42CFB1527DFDE7900862737 /* nginx-site.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "nginx-site.test"; sourceTree = "<group>"; };
C42CFB1727DFDFDC00862737 /* nginx-site-isolated.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "nginx-site-isolated.test"; sourceTree = "<group>"; };
@ -754,6 +757,7 @@
C42C49DA27C2806F0074ABAC /* MainMenu+FixMyValet.swift */,
C4F361602836BFD9003598CC /* MainMenu+Actions.swift */,
C47331A1247093B7009A0597 /* StatusMenu.swift */,
C42800A928452AA10099C999 /* StatusMenu+Items.swift */,
C48D0C9525CC80B100CC7490 /* HeaderView.swift */,
C48D0C9925CC888B00CC7490 /* HeaderView.xib */,
C48D0CA225CC992000CC7490 /* StatsView.swift */,
@ -1211,6 +1215,7 @@
C41CD0292628D8EE0065BBED /* GlobalKeybindPreference.swift in Sources */,
C4EE55AB27708B9E001DF387 /* Preview.swift in Sources */,
C44067F727E258410045BD4E /* DomainListPhpCell.swift in Sources */,
C42800AA28452AA10099C999 /* StatusMenu+Items.swift in Sources */,
C415D3B72770F294005EF286 /* Actions.swift in Sources */,
C4AC51FC27E27F47008528CA /* DomainListKindCell.swift in Sources */,
C4F361612836BFD9003598CC /* MainMenu+Actions.swift in Sources */,
@ -1349,6 +1354,7 @@
C40C7F3127722E8D00DDDCDC /* Logger.swift in Sources */,
C4068CAB27B0890D00544CD5 /* MenuBarIcons.swift in Sources */,
C4F30B09278E1A0E00755FCE /* CustomPrefs.swift in Sources */,
C42800AB28452AA50099C999 /* StatusMenu+Items.swift in Sources */,
C40FE738282ABA4F00A302C2 /* AppVersion.swift in Sources */,
C415D3E92770F692005EF286 /* AppDelegate+InterApp.swift in Sources */,
C484437C2804BB560041A78A /* ValetProxyScanner.swift in Sources */,

View File

@ -47,5 +47,5 @@ class EditorMenuItem: NSMenuItem {
}
class PresetMenuItem: NSMenuItem {
var preset: CustomPrefs.Preset?
var preset: Preset?
}

View File

@ -71,4 +71,22 @@ extension String {
}
}
var stripped: String {
do {
guard let data = self.data(using: .unicode) else {
return ""
}
let attributed = try NSAttributedString(
data: data,
options: [
.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil
)
return attributed.string
} catch {
return ""
}
}
}

View File

@ -65,7 +65,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
override init() {
logger.verbosity = .info
#if DEBUG
logger.verbosity = .performance
// logger.verbosity = .performance
#endif
if CommandLine.arguments.contains("--v") {
logger.verbosity = .performance

View File

@ -0,0 +1,221 @@
//
// StatusMenu+Items.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 30/05/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
//
import Cocoa
extension StatusMenu {
// MARK: Remaining Menu Items
func addConfigurationMenuItems() {
self.addItem(HeaderView.asMenuItem(text: "mi_configuration".localized))
self.addItem(
NSMenuItem(title: "mi_php_config".localized,
action: #selector(MainMenu.openActiveConfigFolder), keyEquivalent: "c")
)
self.addItem(
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)
}
func addStatsMenuItem() {
guard let stats = PhpEnv.phpInstall.limits else { return }
self.addItem(StatsView.asMenuItem(
memory: stats.memory_limit,
post: stats.post_max_size,
upload: stats.upload_max_filesize)
)
}
func addExtensionsMenuItems() {
self.addItem(HeaderView.asMenuItem(text: "mi_detected_extensions".localized))
if PhpEnv.phpInstall.extensions.isEmpty {
self.addItem(NSMenuItem(title: "mi_no_extensions_detected".localized, action: nil, keyEquivalent: ""))
}
var shortcutKey = 1
for phpExtension in PhpEnv.phpInstall.extensions {
self.addExtensionItem(phpExtension, shortcutKey)
shortcutKey += 1
}
}
func addPresetsMenuItem() {
if Preferences.custom.presets.isEmpty {
return
}
let presets = NSMenuItem(title: "Configuration Presets", action: nil, keyEquivalent: "")
let presetsMenu = NSMenu()
presetsMenu.addItem(NSMenuItem.separator())
presetsMenu.addItem(HeaderView.asMenuItem(text: "Apply Configuration Presets"))
for preset in Preferences.custom.presets {
let presetMenuItem = PresetMenuItem(
title: preset.getMenuItemText(),
action: #selector(MainMenu.togglePreset(sender:)),
keyEquivalent: ""
)
if let attributedString = try? NSMutableAttributedString(
data: preset.getMenuItemText().data(using: .utf8)!,
options: [.documentType: NSAttributedString.DocumentType.html],
documentAttributes: nil
) {
/*
attributedString.addAttribute(
.font,
value: NSFont.systemFont(ofSize: 12),
range: NSRange(location: 0, length: attributedString.length)
)
*/
presetMenuItem.attributedTitle = attributedString
}
presetMenuItem.preset = preset
presetsMenu.addItem(presetMenuItem)
}
presetsMenu.addItem(NSMenuItem.separator())
presetsMenu.addItem(NSMenuItem(
title: "Revert to Previous Configuration...",
action: #selector(MainMenu.restartDnsMasq), keyEquivalent: "")
)
presetsMenu.addItem(NSMenuItem.separator())
presetsMenu.addItem(NSMenuItem(
title: "\(Preferences.custom.presets.count) profiles loaded from configuration file",
action: nil, keyEquivalent: "")
)
for item in presetsMenu.items {
item.target = MainMenu.shared
}
self.setSubmenu(presetsMenu, for: presets)
self.addItem(presets)
}
func addXdebugMenuItem() {
if !Xdebug.enabled {
return
}
let xdebugSwitch = NSMenuItem(
title: "mi_xdebug_mode".localized,
action: nil,
keyEquivalent: ""
)
let xdebugModesMenu = NSMenu()
let activeModes = Xdebug.activeModes
xdebugModesMenu.addItem(HeaderView.asMenuItem(text: "Available Modes"))
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: "Actions"))
xdebugModesMenu.addItem(
withTitle: "Disable All",
action: #selector(MainMenu.disableAllXdebugModes),
keyEquivalent: ""
)
for item in xdebugModesMenu.items {
item.target = MainMenu.shared
}
self.setSubmenu(xdebugModesMenu, for: xdebugSwitch)
self.addItem(xdebugSwitch)
}
func addFirstAidAndServicesMenuItems() {
let services = NSMenuItem(title: "mi_other".localized, action: nil, keyEquivalent: "")
let servicesMenu = NSMenu()
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_all_services".localized,
action: #selector(MainMenu.restartAllServices), keyEquivalent: "s")
)
servicesMenu.addItem(
NSMenuItem(title: "mi_stop_all_services".localized,
action: #selector(MainMenu.stopAllServices), keyEquivalent: "s"),
withKeyModifier: [.command, .shift]
)
servicesMenu.addItem(NSMenuItem.separator())
servicesMenu.addItem(HeaderView.asMenuItem(text: "mi_manual_actions".localized))
servicesMenu.addItem(
NSMenuItem(title: "mi_php_refresh".localized,
action: #selector(MainMenu.reloadPhpMonitorMenuInForeground), keyEquivalent: "r")
)
for item in servicesMenu.items {
item.target = MainMenu.shared
}
self.setSubmenu(servicesMenu, for: services)
self.addItem(services)
}
}

View File

@ -87,201 +87,9 @@ class StatusMenu: NSMenu {
action: #selector(MainMenu.terminateApp), keyEquivalent: "q"))
}
// MARK: Remaining Menu Items
func addConfigurationMenuItems() {
self.addItem(HeaderView.asMenuItem(text: "mi_configuration".localized))
self.addItem(
NSMenuItem(title: "mi_php_config".localized,
action: #selector(MainMenu.openActiveConfigFolder), keyEquivalent: "c")
)
self.addItem(
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)
}
func addStatsMenuItem() {
guard let stats = PhpEnv.phpInstall.limits else { return }
self.addItem(StatsView.asMenuItem(
memory: stats.memory_limit,
post: stats.post_max_size,
upload: stats.upload_max_filesize)
)
}
func addExtensionsMenuItems() {
self.addItem(HeaderView.asMenuItem(text: "mi_detected_extensions".localized))
if PhpEnv.phpInstall.extensions.isEmpty {
self.addItem(NSMenuItem(title: "mi_no_extensions_detected".localized, action: nil, keyEquivalent: ""))
}
var shortcutKey = 1
for phpExtension in PhpEnv.phpInstall.extensions {
self.addExtensionItem(phpExtension, shortcutKey)
shortcutKey += 1
}
}
func addPresetsMenuItem() {
if Preferences.custom.presets.isEmpty {
return
}
let presets = NSMenuItem(title: "Configuration Presets", action: nil, keyEquivalent: "")
let presetsMenu = NSMenu()
presetsMenu.addItem(NSMenuItem.separator())
presetsMenu.addItem(HeaderView.asMenuItem(text: "Apply Configuration Presets"))
for preset in Preferences.custom.presets {
let presetMenuItem = PresetMenuItem(
title: "\(preset.name) (\(preset.extensions.count) extension, \(preset.configuration.count) prefs)",
action: #selector(MainMenu.togglePreset(sender:)),
keyEquivalent: ""
)
presetMenuItem.preset = preset
presetsMenu.addItem(presetMenuItem)
}
presetsMenu.addItem(NSMenuItem.separator())
presetsMenu.addItem(NSMenuItem(
title: "Revert to Previous Configuration...",
action: #selector(MainMenu.restartDnsMasq), keyEquivalent: "")
)
presetsMenu.addItem(NSMenuItem.separator())
presetsMenu.addItem(NSMenuItem(
title: "\(Preferences.custom.presets.count) profiles loaded from configuration file",
action: nil, keyEquivalent: "")
)
for item in presetsMenu.items {
item.target = MainMenu.shared
}
self.setSubmenu(presetsMenu, for: presets)
self.addItem(presets)
}
func addXdebugMenuItem() {
if !Xdebug.enabled {
return
}
let xdebugSwitch = NSMenuItem(
title: "mi_xdebug_mode".localized,
action: nil,
keyEquivalent: ""
)
let xdebugModesMenu = NSMenu()
let activeModes = Xdebug.activeModes
xdebugModesMenu.addItem(HeaderView.asMenuItem(text: "Available Modes"))
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: "Actions"))
xdebugModesMenu.addItem(
withTitle: "Disable All",
action: #selector(MainMenu.disableAllXdebugModes),
keyEquivalent: ""
)
for item in xdebugModesMenu.items {
item.target = MainMenu.shared
}
self.setSubmenu(xdebugModesMenu, for: xdebugSwitch)
self.addItem(xdebugSwitch)
}
func addFirstAidAndServicesMenuItems() {
let services = NSMenuItem(title: "mi_other".localized, action: nil, keyEquivalent: "")
let servicesMenu = NSMenu()
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_all_services".localized,
action: #selector(MainMenu.restartAllServices), keyEquivalent: "s")
)
servicesMenu.addItem(
NSMenuItem(title: "mi_stop_all_services".localized,
action: #selector(MainMenu.stopAllServices), keyEquivalent: "s"),
withKeyModifier: [.command, .shift]
)
servicesMenu.addItem(NSMenuItem.separator())
servicesMenu.addItem(HeaderView.asMenuItem(text: "mi_manual_actions".localized))
servicesMenu.addItem(
NSMenuItem(title: "mi_php_refresh".localized,
action: #selector(MainMenu.reloadPhpMonitorMenuInForeground), keyEquivalent: "r")
)
for item in servicesMenu.items {
item.target = MainMenu.shared
}
self.setSubmenu(servicesMenu, for: services)
self.addItem(services)
}
// MARK: Private Helpers
private func addSwitchToPhpMenuItems() {
internal func addSwitchToPhpMenuItems() {
var shortcutKey = 1
for index in (0..<PhpEnv.shared.availablePhpVersions.count).reversed() {
@ -308,7 +116,7 @@ class StatusMenu: NSMenu {
}
}
private func addExtensionItem(_ phpExtension: PhpExtension, _ shortcutKey: Int) {
internal func addExtensionItem(_ phpExtension: PhpExtension, _ shortcutKey: Int) {
let keyEquivalent = shortcutKey < 9 ? "\(shortcutKey)" : ""
let menuItem = ExtensionMenuItem(

View File

@ -16,44 +16,80 @@ struct CustomPrefs: Decodable {
case scanApps = "scan_apps"
case presets = "presets"
}
}
struct Preset: Decodable {
let name: String
let extensions: [String: Bool]
let configuration: [String: String?]
struct Preset: Decodable {
let name: String
let version: String?
let extensions: [String: Bool]
let configuration: [String: String?]
public func apply() {
// Apply the configuration changes first
for conf in configuration {
applyConfigurationValue(key: conf.key, value: conf.value ?? "")
}
public enum CodingKeys: String, CodingKey {
case version = "php",
name = "name",
extensions = "extensions",
configuration = "configuration"
}
// Apply the extension changes in-place afterward
for ext in extensions {
for foundExt in PhpEnv.phpInstall.extensions
where foundExt.name == ext.key && foundExt.enabled != ext.value {
Log.info("Toggling extension \(foundExt.name) in \(foundExt.file)")
foundExt.toggle()
break
}
}
public func getMenuItemText() -> String {
var info = extensions.count == 1
? "preset.extension".localized(extensions.count)
: "preset.extensions".localized(extensions.count)
info += ", "
info += configuration.count == 1
? "preset.preference".localized(configuration.count)
: "preset.preferences".localized(configuration.count)
Actions.restartPhpFpm()
if self.version == nil || !PhpEnv.shared.availablePhpVersions.contains(self.version!) {
return "<span style=\"font-family: '-apple-system'; font-size: 12px;\">"
+ "<b>\(name.stripped)</b><br/>"
+ "<i style=\"font-size: 11px;\">"
+ info + "</i>"
+ "</span>"
}
private func applyConfigurationValue(key: String, value: String) {
guard let file = PhpEnv.shared.getConfigFile(forKey: key) else {
return
}
return "<span style=\"font-family: '-apple-system'; font-size: 12px;\">"
+ "<b>\(name.stripped)</b><br/>"
+ "<i style=\"font-size: 11px;\">"
+ "Switches to PHP \(version!)<br/>"
+ info + "</i>"
+ "</span>"
}
do {
if file.has(key: key) {
Log.info("Setting config value \(key) in \(file.filePath)")
try file.replace(key: key, value: value)
}
} catch {
Log.err("Setting \(key) to \(value) failed.")
public func apply() {
// Apply the PHP version if is considered a valid version
// TODO
// Apply the configuration changes first
for conf in configuration {
applyConfigurationValue(key: conf.key, value: conf.value ?? "")
}
// Apply the extension changes in-place afterward
for ext in extensions {
for foundExt in PhpEnv.phpInstall.extensions
where foundExt.name == ext.key && foundExt.enabled != ext.value {
Log.info("Toggling extension \(foundExt.name) in \(foundExt.file)")
foundExt.toggle()
break
}
}
Actions.restartPhpFpm()
}
private func applyConfigurationValue(key: String, value: String) {
guard let file = PhpEnv.shared.getConfigFile(forKey: key) else {
return
}
do {
if file.has(key: key) {
Log.info("Setting config value \(key) in \(file.filePath)")
try file.replace(key: key, value: value)
}
} catch {
Log.err("Setting \(key) to \(value) failed.")
}
}
}

View File

@ -167,6 +167,13 @@
"driver.not_detected" = "Other";
// PRESET
"preset.extension" = "%i extension";
"preset.extensions" = "%i extensions";
"preset.preference" = "%i preference";
"preset.preferences" = "%i preferences";
// EDITORS
"editors.alert.try_again" = "Try Again";