mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 12:00:09 +02:00
👌 Granular notification control
This commit is contained in:
@ -7,7 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
5420395926135DC100FB00FA /* GeneralPreferencesVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5420395826135DC100FB00FA /* GeneralPreferencesVC.swift */; };
|
||||
5420395926135DC100FB00FA /* PrefsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5420395826135DC100FB00FA /* PrefsVC.swift */; };
|
||||
5420395F2613607600FB00FA /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5420395E2613607600FB00FA /* Preferences.swift */; };
|
||||
5489625828312FAD004F647A /* CreatedFromFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5489625728312FAD004F647A /* CreatedFromFile.swift */; };
|
||||
5489625928313231004F647A /* CreatedFromFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5489625728312FAD004F647A /* CreatedFromFile.swift */; };
|
||||
@ -143,7 +143,7 @@
|
||||
C476FF9822B0DD830098105B /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C476FF9722B0DD830098105B /* Alert.swift */; };
|
||||
C4811D2422D70A4700B5F6B3 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2322D70A4700B5F6B3 /* App.swift */; };
|
||||
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */; };
|
||||
C481F79726164A78004FBCFF /* GeneralPreferencesVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5420395826135DC100FB00FA /* GeneralPreferencesVC.swift */; };
|
||||
C481F79726164A78004FBCFF /* PrefsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5420395826135DC100FB00FA /* PrefsVC.swift */; };
|
||||
C481F79A26164A7C004FBCFF /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5420395E2613607600FB00FA /* Preferences.swift */; };
|
||||
C484437B2804BB560041A78A /* ValetProxyScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C484437A2804BB560041A78A /* ValetProxyScanner.swift */; };
|
||||
C484437C2804BB560041A78A /* ValetProxyScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = C484437A2804BB560041A78A /* ValetProxyScanner.swift */; };
|
||||
@ -288,7 +288,7 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
5420395826135DC100FB00FA /* GeneralPreferencesVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralPreferencesVC.swift; sourceTree = "<group>"; };
|
||||
5420395826135DC100FB00FA /* PrefsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefsVC.swift; sourceTree = "<group>"; };
|
||||
5420395E2613607600FB00FA /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
|
||||
5489625728312FAD004F647A /* CreatedFromFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatedFromFile.swift; sourceTree = "<group>"; };
|
||||
54A18D3F282A566E000A0D81 /* nginx-secure-proxy-custom-tld.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "nginx-secure-proxy-custom-tld.test"; sourceTree = "<group>"; };
|
||||
@ -474,7 +474,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C4998F092617633900B2526E /* PrefsWC.swift */,
|
||||
5420395826135DC100FB00FA /* GeneralPreferencesVC.swift */,
|
||||
5420395826135DC100FB00FA /* PrefsVC.swift */,
|
||||
5420395E2613607600FB00FA /* Preferences.swift */,
|
||||
C4C3ED4227834C5200AB15D8 /* CustomPrefs.swift */,
|
||||
C4068CA927B0890D00544CD5 /* MenuBarIcons.swift */,
|
||||
@ -1202,7 +1202,7 @@
|
||||
C4F8C0A422D4F12C002EFE61 /* DateExtension.swift in Sources */,
|
||||
C4AF9F7A2754499000D44ED0 /* Valet.swift in Sources */,
|
||||
C4C0E8EA27F88B80002D32A9 /* ValetProxy+Fake.swift in Sources */,
|
||||
5420395926135DC100FB00FA /* GeneralPreferencesVC.swift in Sources */,
|
||||
5420395926135DC100FB00FA /* PrefsVC.swift in Sources */,
|
||||
C43603A0275E67610028EFC6 /* AppDelegate+Notifications.swift in Sources */,
|
||||
5489625828312FAD004F647A /* CreatedFromFile.swift in Sources */,
|
||||
C4068CA727B07A1300544CD5 /* SelectPreferenceView.swift in Sources */,
|
||||
@ -1368,7 +1368,7 @@
|
||||
C4D936CB27E3EE4A00BD69FE /* DomainListCellProtocol.swift in Sources */,
|
||||
C4B97B76275CF08C003F3378 /* AppDelegate+MenuOutlets.swift in Sources */,
|
||||
C4F780CD25D80B75000DBC97 /* Alert.swift in Sources */,
|
||||
C481F79726164A78004FBCFF /* GeneralPreferencesVC.swift in Sources */,
|
||||
C481F79726164A78004FBCFF /* PrefsVC.swift in Sources */,
|
||||
C41E871B2763D42300161EE0 /* DomainListVC+ContextMenu.swift in Sources */,
|
||||
C40C7F3127722E8D00DDDCDC /* Logger.swift in Sources */,
|
||||
C4068CAB27B0890D00544CD5 /* MenuBarIcons.swift in Sources */,
|
||||
|
@ -10,7 +10,11 @@ import UserNotifications
|
||||
|
||||
class LocalNotification {
|
||||
|
||||
public static func send(title: String, subtitle: String) {
|
||||
public static func send(title: String, subtitle: String, preference: PreferenceName) {
|
||||
if !Preferences.isEnabled(preference) {
|
||||
return
|
||||
}
|
||||
|
||||
let content = UNMutableNotificationContent()
|
||||
content.title = title
|
||||
content.body = subtitle
|
||||
|
@ -378,7 +378,7 @@
|
||||
</viewController>
|
||||
<customObject id="eQC-8B-FkX" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="835" y="-28"/>
|
||||
<point key="canvasLocation" x="844" y="-153"/>
|
||||
</scene>
|
||||
<!--Tab View Controller-->
|
||||
<scene sceneID="B5x-d3-c7D">
|
||||
|
@ -69,7 +69,8 @@ extension DomainListVC {
|
||||
.localized(
|
||||
"\(selectedSite.name).\(Valet.shared.config.tld)",
|
||||
newState
|
||||
)
|
||||
),
|
||||
preference: .notifyAboutSecureToggle
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,8 @@ class ComposerWindow {
|
||||
if shouldNotify {
|
||||
LocalNotification.send(
|
||||
title: "alert.composer_success.title".localized,
|
||||
subtitle: "alert.composer_success.info".localized
|
||||
subtitle: "alert.composer_success.info".localized,
|
||||
preference: .notifyAboutGlobalComposerStatus
|
||||
)
|
||||
}
|
||||
window = nil
|
||||
|
@ -56,7 +56,8 @@ extension MainMenu {
|
||||
DispatchQueue.main.async {
|
||||
LocalNotification.send(
|
||||
title: "notification.services_restarted".localized,
|
||||
subtitle: "notification.services_restarted_desc".localized
|
||||
subtitle: "notification.services_restarted_desc".localized,
|
||||
preference: .notifyAboutServices
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -69,7 +70,8 @@ extension MainMenu {
|
||||
DispatchQueue.main.async {
|
||||
LocalNotification.send(
|
||||
title: "notification.services_stopped".localized,
|
||||
subtitle: "notification.services_stopped_desc".localized
|
||||
subtitle: "notification.services_stopped_desc".localized,
|
||||
preference: .notifyAboutServices
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -165,8 +167,8 @@ extension MainMenu {
|
||||
)
|
||||
)
|
||||
.withPrimary(text: "alert.revert_description.ok".localized, action: { alert in
|
||||
self.performRollback()
|
||||
alert.close(with: .OK)
|
||||
self.performRollback()
|
||||
})
|
||||
.withSecondary(text: "alert.revert_description.cancel".localized)
|
||||
.show()
|
||||
|
@ -77,7 +77,8 @@ extension MainMenu {
|
||||
private func notifyAboutVersionChange(to version: String) {
|
||||
LocalNotification.send(
|
||||
title: String(format: "notification.version_changed_title".localized, version),
|
||||
subtitle: String(format: "notification.version_changed_desc".localized, version)
|
||||
subtitle: String(format: "notification.version_changed_desc".localized, version),
|
||||
preference: .notifyAboutVersionChange
|
||||
)
|
||||
|
||||
PhpEnv.phpInstall.notifyAboutBrokenPhpFpm()
|
||||
|
@ -1,156 +0,0 @@
|
||||
//
|
||||
// GeneralPreferencesVC.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 30/03/2021.
|
||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import Carbon
|
||||
|
||||
class GenericPreferenceVC: NSViewController {
|
||||
|
||||
// MARK: - Content
|
||||
|
||||
@IBOutlet weak var stackView: NSStackView!
|
||||
|
||||
var views: [NSView] = []
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.views.forEach({ self.stackView.addArrangedSubview($0) })
|
||||
}
|
||||
|
||||
// MARK: - Deinitialization
|
||||
|
||||
deinit {
|
||||
Log.perf("PrefsVC deallocated")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class GeneralPreferencesVC: GenericPreferenceVC {
|
||||
|
||||
// MARK: - Icon and title
|
||||
|
||||
var icon: String = "gear"
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
public static func fromStoryboard() -> GenericPreferenceVC {
|
||||
let vc = NSStoryboard(name: "Main", bundle: nil)
|
||||
.instantiateController(withIdentifier: "preferencesTemplateVC") as! GenericPreferenceVC
|
||||
|
||||
vc.views = [
|
||||
getDynamicIconPreferenceView(),
|
||||
getIconOptionsPreferenceView(),
|
||||
getIconDensityPreferenceView(),
|
||||
getAutoRestartPreferenceView(),
|
||||
getAutomaticComposerUpdatePreferenceView(),
|
||||
// getShortcutPreferenceView(),
|
||||
getIntegrationsPreferenceView(),
|
||||
getAutomaticUpdateCheckPreferenceView()
|
||||
]
|
||||
|
||||
return vc
|
||||
}
|
||||
|
||||
private static func getDynamicIconPreferenceView() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "prefs.dynamic_icon".localized,
|
||||
descriptionText: "prefs.dynamic_icon_desc".localized,
|
||||
checkboxText: "prefs.dynamic_icon_title".localized,
|
||||
preference: .shouldDisplayDynamicIcon,
|
||||
action: {
|
||||
MainMenu.shared.refreshIcon()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private static func getIconOptionsPreferenceView() -> NSView {
|
||||
return SelectPreferenceView.make(
|
||||
sectionText: "",
|
||||
descriptionText: "prefs.icon_options_desc".localized,
|
||||
options: MenuBarIcon.allCases.map({ return $0.rawValue }),
|
||||
localizationPrefix: "prefs.icon_options",
|
||||
preference: .iconTypeToDisplay,
|
||||
action: {
|
||||
MainMenu.shared.refreshIcon()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private static func getIconDensityPreferenceView() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "prefs.info_density".localized,
|
||||
descriptionText: "prefs.display_full_php_version_desc".localized,
|
||||
checkboxText: "prefs.display_full_php_version".localized,
|
||||
preference: .fullPhpVersionDynamicIcon,
|
||||
action: {
|
||||
MainMenu.shared.refreshIcon()
|
||||
MainMenu.shared.rebuild()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private static func getAutoRestartPreferenceView() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "prefs.services".localized,
|
||||
descriptionText: "prefs.auto_restart_services_desc".localized,
|
||||
checkboxText: "prefs.auto_restart_services_title".localized,
|
||||
preference: .autoServiceRestartAfterExtensionToggle,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
private static func getAutomaticComposerUpdatePreferenceView() -> NSView {
|
||||
CheckboxPreferenceView.make(
|
||||
sectionText: "prefs.switcher".localized,
|
||||
descriptionText: "prefs.auto_composer_update_desc".localized,
|
||||
checkboxText: "prefs.auto_composer_update_title".localized,
|
||||
preference: .autoComposerGlobalUpdateAfterSwitch,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
private static func getShortcutPreferenceView() -> NSView {
|
||||
return HotkeyPreferenceView.make(
|
||||
sectionText: "prefs.global_shortcut".localized,
|
||||
descriptionText: "prefs.shortcut_desc".localized,
|
||||
self
|
||||
)
|
||||
}
|
||||
*/
|
||||
|
||||
private static func getIntegrationsPreferenceView() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "prefs.integrations".localized,
|
||||
descriptionText: "prefs.open_protocol_desc".localized,
|
||||
checkboxText: "prefs.open_protocol_title".localized,
|
||||
preference: .allowProtocolForIntegrations,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
private static func getAutomaticUpdateCheckPreferenceView() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "prefs.updates".localized,
|
||||
descriptionText: "prefs.automatic_update_check_desc".localized,
|
||||
checkboxText: "prefs.automatic_update_check_title".localized,
|
||||
preference: .automaticBackgroundUpdateCheck,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: - Listening for hotkey delegate
|
||||
|
||||
var listeningForHotkeyView: HotkeyPreferenceView?
|
||||
|
||||
override func viewWillDisappear() {
|
||||
if listeningForHotkeyView !== nil {
|
||||
listeningForHotkeyView = nil
|
||||
}
|
||||
}
|
||||
}
|
@ -12,15 +12,28 @@ import Foundation
|
||||
These are the keys used for every preference in the app.
|
||||
*/
|
||||
enum PreferenceName: String {
|
||||
// FIRST-TIME LAUNCH
|
||||
case wasLaunchedBefore = "launched_before"
|
||||
case shouldDisplayDynamicIcon = "use_dynamic_icon"
|
||||
case iconTypeToDisplay = "icon_type_to_display"
|
||||
case fullPhpVersionDynamicIcon = "full_php_in_menu_bar"
|
||||
|
||||
// GENERAL
|
||||
case autoServiceRestartAfterExtensionToggle = "auto_restart_after_extension_toggle"
|
||||
case autoComposerGlobalUpdateAfterSwitch = "auto_composer_global_update_after_switch"
|
||||
case allowProtocolForIntegrations = "allow_protocol_for_integrations"
|
||||
case globalHotkey = "global_hotkey"
|
||||
case automaticBackgroundUpdateCheck = "backgroundUpdateCheck"
|
||||
|
||||
// APPEARANCE
|
||||
case shouldDisplayDynamicIcon = "use_dynamic_icon"
|
||||
case iconTypeToDisplay = "icon_type_to_display"
|
||||
case fullPhpVersionDynamicIcon = "full_php_in_menu_bar"
|
||||
|
||||
// NOTIFICATIONS
|
||||
case notifyAboutVersionChange = "notify_about_version_change"
|
||||
case notifyAboutPhpFpmRestart = "notify_about_php_fpm_restart"
|
||||
case notifyAboutServices = "notify_about_services_restart"
|
||||
case notifyAboutPresets = "notify_about_presets"
|
||||
case notifyAboutSecureToggle = "notify_about_secure_toggle"
|
||||
case notifyAboutGlobalComposerStatus = "notify_about_composer_status"
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,14 +83,25 @@ class Preferences {
|
||||
*/
|
||||
static func handleFirstTimeLaunch() {
|
||||
UserDefaults.standard.register(defaults: [
|
||||
/// Preferences
|
||||
PreferenceName.shouldDisplayDynamicIcon.rawValue: true,
|
||||
PreferenceName.iconTypeToDisplay.rawValue: MenuBarIcon.iconPhp.rawValue,
|
||||
PreferenceName.fullPhpVersionDynamicIcon.rawValue: false,
|
||||
/// Preferences: General
|
||||
PreferenceName.autoServiceRestartAfterExtensionToggle.rawValue: true,
|
||||
PreferenceName.autoComposerGlobalUpdateAfterSwitch.rawValue: false,
|
||||
PreferenceName.allowProtocolForIntegrations.rawValue: true,
|
||||
PreferenceName.automaticBackgroundUpdateCheck.rawValue: true,
|
||||
|
||||
/// Preferences: Appearance
|
||||
PreferenceName.shouldDisplayDynamicIcon.rawValue: true,
|
||||
PreferenceName.iconTypeToDisplay.rawValue: MenuBarIcon.iconPhp.rawValue,
|
||||
PreferenceName.fullPhpVersionDynamicIcon.rawValue: false,
|
||||
|
||||
/// Preferences: Notifications
|
||||
PreferenceName.notifyAboutVersionChange.rawValue: true,
|
||||
PreferenceName.notifyAboutPhpFpmRestart.rawValue: true,
|
||||
PreferenceName.notifyAboutServices.rawValue: true,
|
||||
PreferenceName.notifyAboutPresets.rawValue: true,
|
||||
PreferenceName.notifyAboutSecureToggle.rawValue: true,
|
||||
PreferenceName.notifyAboutGlobalComposerStatus.rawValue: true,
|
||||
|
||||
/// Stats
|
||||
InternalStats.switchCount.rawValue: 0,
|
||||
InternalStats.launchCount.rawValue: 0,
|
||||
@ -137,7 +161,8 @@ class Preferences {
|
||||
private static func cache() -> [PreferenceName: Any] {
|
||||
return [
|
||||
// Part 1: Always Booleans
|
||||
.shouldDisplayDynamicIcon: UserDefaults.standard.bool(
|
||||
.shouldDisplayDynamicIcon:
|
||||
UserDefaults.standard.bool(
|
||||
forKey: PreferenceName.shouldDisplayDynamicIcon.rawValue) as Any,
|
||||
.fullPhpVersionDynamicIcon: UserDefaults.standard.bool(
|
||||
forKey: PreferenceName.fullPhpVersionDynamicIcon.rawValue) as Any,
|
||||
@ -150,6 +175,19 @@ class Preferences {
|
||||
.automaticBackgroundUpdateCheck: UserDefaults.standard.bool(
|
||||
forKey: PreferenceName.automaticBackgroundUpdateCheck.rawValue) as Any,
|
||||
|
||||
.notifyAboutVersionChange: UserDefaults.standard.bool(
|
||||
forKey: PreferenceName.notifyAboutVersionChange.rawValue) as Any,
|
||||
.notifyAboutPhpFpmRestart: UserDefaults.standard.bool(
|
||||
forKey: PreferenceName.notifyAboutPhpFpmRestart.rawValue) as Any,
|
||||
.notifyAboutServices: UserDefaults.standard.bool(
|
||||
forKey: PreferenceName.notifyAboutServices.rawValue) as Any,
|
||||
.notifyAboutPresets: UserDefaults.standard.bool(
|
||||
forKey: PreferenceName.notifyAboutPresets.rawValue) as Any,
|
||||
.notifyAboutSecureToggle: UserDefaults.standard.bool(
|
||||
forKey: PreferenceName.notifyAboutSecureToggle.rawValue) as Any,
|
||||
.notifyAboutGlobalComposerStatus: UserDefaults.standard.bool(
|
||||
forKey: PreferenceName.notifyAboutGlobalComposerStatus.rawValue) as Any,
|
||||
|
||||
// Part 2: Always Strings
|
||||
.globalHotkey: UserDefaults.standard.string(
|
||||
forKey: PreferenceName.globalHotkey.rawValue) as Any,
|
||||
|
244
phpmon/Domain/Preferences/PrefsVC.swift
Normal file
244
phpmon/Domain/Preferences/PrefsVC.swift
Normal file
@ -0,0 +1,244 @@
|
||||
//
|
||||
// PrefsVC.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 30/03/2021.
|
||||
// Copyright © 2022 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import Carbon
|
||||
|
||||
class GenericPreferenceVC: NSViewController {
|
||||
|
||||
// MARK: - Content
|
||||
|
||||
@IBOutlet weak var stackView: NSStackView!
|
||||
|
||||
var views: [NSView] = []
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.views.forEach({ self.stackView.addArrangedSubview($0) })
|
||||
}
|
||||
|
||||
// MARK: - Deinitialization
|
||||
|
||||
deinit {
|
||||
Log.perf("PrefsVC deallocated")
|
||||
}
|
||||
|
||||
func getDynamicIconPV() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "prefs.dynamic_icon".localized,
|
||||
descriptionText: "prefs.dynamic_icon_desc".localized,
|
||||
checkboxText: "prefs.dynamic_icon_title".localized,
|
||||
preference: .shouldDisplayDynamicIcon,
|
||||
action: {
|
||||
MainMenu.shared.refreshIcon()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
func getIconOptionsPV() -> NSView {
|
||||
return SelectPreferenceView.make(
|
||||
sectionText: "",
|
||||
descriptionText: "prefs.icon_options_desc".localized,
|
||||
options: MenuBarIcon.allCases.map({ return $0.rawValue }),
|
||||
localizationPrefix: "prefs.icon_options",
|
||||
preference: .iconTypeToDisplay,
|
||||
action: {
|
||||
MainMenu.shared.refreshIcon()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
func getIconDensityPV() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "prefs.info_density".localized,
|
||||
descriptionText: "prefs.display_full_php_version_desc".localized,
|
||||
checkboxText: "prefs.display_full_php_version".localized,
|
||||
preference: .fullPhpVersionDynamicIcon,
|
||||
action: {
|
||||
MainMenu.shared.refreshIcon()
|
||||
MainMenu.shared.rebuild()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
func getAutoRestartPV() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "prefs.services".localized,
|
||||
descriptionText: "prefs.auto_restart_services_desc".localized,
|
||||
checkboxText: "prefs.auto_restart_services_title".localized,
|
||||
preference: .autoServiceRestartAfterExtensionToggle,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
func getAutomaticComposerUpdatePV() -> NSView {
|
||||
CheckboxPreferenceView.make(
|
||||
sectionText: "prefs.switcher".localized,
|
||||
descriptionText: "prefs.auto_composer_update_desc".localized,
|
||||
checkboxText: "prefs.auto_composer_update_title".localized,
|
||||
preference: .autoComposerGlobalUpdateAfterSwitch,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
func getShortcutPV() -> NSView {
|
||||
return HotkeyPreferenceView.make(
|
||||
sectionText: "prefs.global_shortcut".localized,
|
||||
descriptionText: "prefs.shortcut_desc".localized,
|
||||
self
|
||||
)
|
||||
}
|
||||
|
||||
func getIntegrationsPV() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "prefs.integrations".localized,
|
||||
descriptionText: "prefs.open_protocol_desc".localized,
|
||||
checkboxText: "prefs.open_protocol_title".localized,
|
||||
preference: .allowProtocolForIntegrations,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
func getAutomaticUpdateCheckPV() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "prefs.updates".localized,
|
||||
descriptionText: "prefs.automatic_update_check_desc".localized,
|
||||
checkboxText: "prefs.automatic_update_check_title".localized,
|
||||
preference: .automaticBackgroundUpdateCheck,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
func getNotifyAboutVersionChangePV() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "prefs.notifications".localized,
|
||||
descriptionText: "prefs.notify_about_version_change_desc".localized,
|
||||
checkboxText: "prefs.notify_about_version_change".localized,
|
||||
preference: .notifyAboutVersionChange,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
func getNotifyAboutPhpFpmChangePV() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "",
|
||||
descriptionText: "prefs.notify_about_php_fpm_change_desc".localized,
|
||||
checkboxText: "prefs.notify_about_php_fpm_change".localized,
|
||||
preference: .notifyAboutPhpFpmRestart,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
func getNotifyAboutServicesPV() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "",
|
||||
descriptionText: "prefs.notify_about_services_desc".localized,
|
||||
checkboxText: "prefs.notify_about_services".localized,
|
||||
preference: .notifyAboutServices,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
func getNotifyAboutPresetsPV() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "",
|
||||
descriptionText: "prefs.notify_about_presets_desc".localized,
|
||||
checkboxText: "prefs.notify_about_presets".localized,
|
||||
preference: .notifyAboutPresets,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
func getNotifyAboutSecureTogglePV() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "",
|
||||
descriptionText: "prefs.notify_about_secure_status_desc".localized,
|
||||
checkboxText: "prefs.notify_about_secure_status".localized,
|
||||
preference: .notifyAboutSecureToggle,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
func getNotifyAboutGlobalComposerStatusPV() -> NSView {
|
||||
return CheckboxPreferenceView.make(
|
||||
sectionText: "",
|
||||
descriptionText: "prefs.notify_about_composer_success_desc".localized,
|
||||
checkboxText: "prefs.notify_about_composer_success".localized,
|
||||
preference: .notifyAboutGlobalComposerStatus,
|
||||
action: {}
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: - Listening for hotkey delegate
|
||||
|
||||
var listeningForHotkeyView: HotkeyPreferenceView?
|
||||
|
||||
override func viewWillDisappear() {
|
||||
if listeningForHotkeyView !== nil {
|
||||
listeningForHotkeyView = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GeneralPreferencesVC: GenericPreferenceVC {
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
public static func fromStoryboard() -> GenericPreferenceVC {
|
||||
let vc = NSStoryboard(name: "Main", bundle: nil)
|
||||
.instantiateController(withIdentifier: "preferencesTemplateVC") as! GenericPreferenceVC
|
||||
|
||||
vc.views = [
|
||||
vc.getAutoRestartPV(),
|
||||
vc.getAutomaticComposerUpdatePV(),
|
||||
vc.getShortcutPV(),
|
||||
vc.getIntegrationsPV(),
|
||||
vc.getAutomaticUpdateCheckPV()
|
||||
]
|
||||
|
||||
return vc
|
||||
}
|
||||
}
|
||||
|
||||
class NotificationPreferencesVC: GenericPreferenceVC {
|
||||
|
||||
public static func fromStoryboard() -> GenericPreferenceVC {
|
||||
let vc = NSStoryboard(name: "Main", bundle: nil)
|
||||
.instantiateController(withIdentifier: "preferencesTemplateVC") as! GenericPreferenceVC
|
||||
|
||||
vc.views = [
|
||||
vc.getNotifyAboutVersionChangePV(),
|
||||
vc.getNotifyAboutPresetsPV(),
|
||||
vc.getNotifyAboutSecureTogglePV(),
|
||||
vc.getNotifyAboutGlobalComposerStatusPV(),
|
||||
vc.getNotifyAboutServicesPV(),
|
||||
vc.getNotifyAboutPhpFpmChangePV()
|
||||
]
|
||||
|
||||
return vc
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class AppearancePreferencesVC: GenericPreferenceVC {
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
public static func fromStoryboard() -> GenericPreferenceVC {
|
||||
let vc = NSStoryboard(name: "Main", bundle: nil)
|
||||
.instantiateController(withIdentifier: "preferencesTemplateVC") as! GenericPreferenceVC
|
||||
|
||||
vc.views = [
|
||||
vc.getDynamicIconPV(),
|
||||
vc.getIconOptionsPV(),
|
||||
vc.getIconDensityPV()
|
||||
]
|
||||
|
||||
return vc
|
||||
}
|
||||
}
|
@ -38,6 +38,8 @@ class PrefsWC: PMWindowController {
|
||||
}
|
||||
|
||||
public static func show(delegate: NSWindowDelegate? = nil) {
|
||||
var justCreated = false
|
||||
|
||||
if App.shared.preferencesWindowController == nil {
|
||||
Self.create(delegate: delegate)
|
||||
|
||||
@ -60,9 +62,16 @@ class PrefsWC: PMWindowController {
|
||||
width: tabVC.view.frame.size.width,
|
||||
height: tabVC.view.frame.size.height
|
||||
)
|
||||
|
||||
justCreated = true
|
||||
}
|
||||
|
||||
App.shared.preferencesWindowController?.showWindow(self)
|
||||
|
||||
if justCreated {
|
||||
App.shared.preferencesWindowController?.positionWindowInTopLeftCorner()
|
||||
}
|
||||
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
}
|
||||
|
||||
@ -77,7 +86,17 @@ class PrefsWC: PMWindowController {
|
||||
PrefTabView(
|
||||
viewController: GeneralPreferencesVC.fromStoryboard(),
|
||||
label: "General",
|
||||
icon: "gear"
|
||||
icon: "gearshape"
|
||||
),
|
||||
PrefTabView(
|
||||
viewController: AppearancePreferencesVC.fromStoryboard(),
|
||||
label: "Appearance",
|
||||
icon: "paintbrush"
|
||||
),
|
||||
PrefTabView(
|
||||
viewController: NotificationPreferencesVC.fromStoryboard(),
|
||||
label: "Notifications",
|
||||
icon: "bell.badge"
|
||||
)
|
||||
]
|
||||
}()
|
||||
@ -87,18 +106,24 @@ class PrefsWC: PMWindowController {
|
||||
override func keyDown(with event: NSEvent) {
|
||||
super.keyDown(with: event)
|
||||
|
||||
/*
|
||||
if let vc = contentViewController as? PrefsVC {
|
||||
guard let tabVC = self.contentViewController as? NSTabViewController else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let selected = tabVC.tabViewItems[tabVC.selectedTabViewItemIndex].viewController else {
|
||||
return
|
||||
}
|
||||
|
||||
if let vc = selected as? GenericPreferenceVC {
|
||||
if vc.listeningForHotkeyView != nil {
|
||||
if event.keyCode == Keys.Escape || event.keyCode == Keys.Space {
|
||||
Log.info("A blacklisted key was pressed, canceling listen!")
|
||||
vc.listeningForHotkeyView = nil
|
||||
vc.listeningForHotkeyView!.unregister(nil)
|
||||
} else {
|
||||
vc.listeningForHotkeyView!.updateShortcut(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,8 +11,7 @@ import Cocoa
|
||||
|
||||
class HotkeyPreferenceView: NSView, XibLoadable {
|
||||
|
||||
#warning("Refactor so this applies to any given preferences VC")
|
||||
weak var delegate: GeneralPreferencesVC?
|
||||
weak var delegate: GenericPreferenceVC?
|
||||
|
||||
@IBOutlet weak var labelSection: NSTextField!
|
||||
@IBOutlet weak var labelDescription: NSTextField!
|
||||
@ -20,7 +19,7 @@ class HotkeyPreferenceView: NSView, XibLoadable {
|
||||
@IBOutlet weak var buttonSetShortcut: NSButton!
|
||||
@IBOutlet weak var buttonClearShortcut: NSButton!
|
||||
|
||||
static func make(sectionText: String, descriptionText: String, _ prefsVC: GeneralPreferencesVC) -> NSView {
|
||||
static func make(sectionText: String, descriptionText: String, _ prefsVC: GenericPreferenceVC) -> NSView {
|
||||
let view = Self.createFromXib()!
|
||||
view.labelSection.stringValue = sectionText
|
||||
view.labelDescription.stringValue = descriptionText
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
struct Preset: Codable {
|
||||
struct Preset: Codable, Equatable {
|
||||
let name: String
|
||||
let version: String?
|
||||
let extensions: [String: Bool]
|
||||
@ -69,6 +69,9 @@ struct Preset: Codable {
|
||||
*/
|
||||
public func apply() {
|
||||
Task {
|
||||
// Was this a rollback?
|
||||
let wasRollback = (self.name == "AutomaticRevertSnapshot")
|
||||
|
||||
// Save the preset that would revert this preset
|
||||
self.persistRevert()
|
||||
|
||||
@ -101,6 +104,21 @@ struct Preset: Codable {
|
||||
|
||||
// Restart PHP FPM process (also reloads menu, which will show the preset rollback)
|
||||
Actions.restartPhpFpm()
|
||||
|
||||
// Show the correct notification
|
||||
if wasRollback {
|
||||
LocalNotification.send(
|
||||
title: "notification.preset_reverted_title".localized,
|
||||
subtitle: "notification.preset_reverted_desc".localized,
|
||||
preference: .notifyAboutPresets
|
||||
)
|
||||
} else {
|
||||
LocalNotification.send(
|
||||
title: "notification.preset_applied_title".localized,
|
||||
subtitle: "notification.preset_applied_desc".localized(self.name),
|
||||
preference: .notifyAboutPresets
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,7 +196,7 @@ struct Preset: Codable {
|
||||
|
||||
public var revertSnapshot: Preset {
|
||||
return Preset(
|
||||
name: "Revert",
|
||||
name: "AutomaticRevertSnapshot",
|
||||
version: diffVersion(),
|
||||
extensions: diffExtensions(),
|
||||
configuration: diffConfiguration()
|
||||
|
@ -193,6 +193,7 @@
|
||||
"prefs.switcher" = "Switcher:";
|
||||
"prefs.integrations" = "Integrations:";
|
||||
"prefs.updates" = "Updates:";
|
||||
"prefs.notifications" = "Notifications:";
|
||||
|
||||
"prefs.icon_options.php" = "Display PHP Icon";
|
||||
"prefs.icon_options.elephant" = "Display Elephant Icon";
|
||||
@ -223,6 +224,24 @@
|
||||
"prefs.shortcut_clear" = "Clear";
|
||||
"prefs.shortcut_desc" = "If a shortcut combination is set up, you can toggle PHP Monitor wherever you are by pressing the key combination you chose. (Cancel choosing a shortcut by pressing the spacebar.)";
|
||||
|
||||
"prefs.notify_about_version_change_desc" = "Displays a notification whenever the active PHP version changes.";
|
||||
"prefs.notify_about_version_change" = "Notify about PHP version switch";
|
||||
|
||||
"prefs.notify_about_php_fpm_change_desc" = "Displays a notification whenever the active PHP-FPM process has restarted due to a configuration change.";
|
||||
"prefs.notify_about_php_fpm_change" = "Notify about PHP-FPM restart";
|
||||
|
||||
"prefs.notify_about_services_desc" = "Displays a notification whenever any of the Homebrew services (installed and configured by Valet) have been restarted or stopped.";
|
||||
"prefs.notify_about_services" = "Notify about services status";
|
||||
|
||||
"prefs.notify_about_presets_desc" = "Displays a notification whenever a preset has been successfully applied or reverted.";
|
||||
"prefs.notify_about_presets" = "Notify about applied presets";
|
||||
|
||||
"prefs.notify_about_secure_status_desc" = "Displays a notification when a domain has been secured or unsecured.";
|
||||
"prefs.notify_about_secure_status" = "Notify about secure/unsecure status";
|
||||
|
||||
"prefs.notify_about_composer_success_desc" = "Displays a notification when the global composer configuration was successfully updated.";
|
||||
"prefs.notify_about_composer_success" = "Notify about global composer update";
|
||||
|
||||
// NOTIFICATIONS
|
||||
|
||||
"notification.version_changed_title" = "PHP %@ now active";
|
||||
@ -237,6 +256,12 @@
|
||||
"notification.services_restarted" = "Valet services restarted";
|
||||
"notification.services_restarted_desc" = "All services have been successfully restarted.";
|
||||
|
||||
"notification.preset_applied_title" = "Preset applied";
|
||||
"notification.preset_applied_desc" = "The preset '%@' has been successfully applied.";
|
||||
|
||||
"notification.preset_reverted_title" = "Preset reverted";
|
||||
"notification.preset_reverted_desc" = "The last preset you applied has been undone. Your previous configuration is now active.";
|
||||
|
||||
// Composer Update
|
||||
"alert.composer_missing.title" = "Composer not found!";
|
||||
"alert.composer_missing.subtitle" = "PHP Monitor could not find Composer. Make sure that Composer is installed and try again.";
|
||||
|
Reference in New Issue
Block a user