diff --git a/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor DEV.xcscheme b/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor DEV.xcscheme
index b0a4d86..8642ae0 100644
--- a/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor DEV.xcscheme
+++ b/PHP Monitor.xcodeproj/xcshareddata/xcschemes/PHP Monitor DEV.xcscheme
@@ -91,7 +91,7 @@
+ isEnabled = "NO">
Void) {
+ let rowToReload = tableView.selectedRow
+
+ waitAndExecute {
+ await Shell.quiet(command)
+ } completion: { [self] in
+ beforeCellReload()
+ tableView.reloadData(forRowIndexes: [rowToReload], columnIndexes: [0, 1, 2, 3, 4])
+ tableView.deselectRow(rowToReload)
+ tableView.selectRowIndexes([rowToReload], byExtendingSelection: true)
}
}
- func toggleSecureForProxy() {
- let originalSecureStatus = selectedProxy!.secured
- let selectedProxy = selectedProxy!
+ private func reloadSelectedRow() {
+ tableView.reloadData(forRowIndexes: [tableView.selectedRow], columnIndexes: [0, 1, 2, 3, 4])
+ tableView.deselectRow(tableView.selectedRow)
+ tableView.selectRowIndexes([tableView.selectedRow], byExtendingSelection: true)
+ }
- self.waitAndExecute {
- // 1. Remove the original proxy
- await Shell.quiet("\(Paths.valet) unproxy \(selectedProxy.domain)")
+ // MARK: - Interactions with `valet` or terminal
- // 2. Add a new proxy, which is either secured/unsecured
- let secure = originalSecureStatus ? "" : " --secure"
- await Shell.quiet("\(Paths.valet) proxy \(selectedProxy.domain) \(selectedProxy.target)\(secure)")
+ @objc func toggleSecure() {
+ if selected is ValetSite {
+ Task { toggleSecureForSite() }
+ } else {
+ Task { await toggleSecureForProxy() }
+ }
+ }
- // 3. Restart nginx
- await Actions.restartNginx()
+ func toggleSecureForProxy() async {
+ guard let proxy = selectedProxy else { return }
- // 4. Reload site list
- Task { @MainActor in
- App.shared.domainListWindowController?.pressedReload(nil)
- }
+ do {
+ // Toggle secure
+ try await proxy.toggleSecure()
+
+ // Reload the UI
+ self.reloadSelectedRow()
+
+ // Send a notification about the new status (if applicable)
+ LocalNotification.send(
+ title: "domain_list.alerts_status_changed.title".localized,
+ subtitle: "domain_list.alerts_status_changed.desc"
+ .localized(
+ "\(proxy.domain).\(Valet.shared.config.tld)",
+ proxy.secured
+ ),
+ preference: .notifyAboutSecureToggle
+ )
+ } catch {
+ let error = error as! ValetInteractionError
+
+ BetterAlert()
+ .withInformation(
+ title: "domain_list.alerts_status_not_changed.title".localized,
+ subtitle: "domain_list.alerts_status_not_changed.desc".localized(error.command)
+ )
+ .withPrimary(text: "OK")
+ .show()
}
}
@@ -79,38 +145,6 @@ extension DomainListVC {
}
}
- @objc func openInBrowser() {
- guard let selected = self.selected else {
- return
- }
-
- guard let url = selected.getListableUrl() else {
- BetterAlert()
- .withInformation(
- title: "domain_list.alert.invalid_folder_name".localized,
- subtitle: "domain_list.alert.invalid_folder_name_desc".localized
- )
- .withPrimary(text: "OK")
- .show()
- return
- }
-
- NSWorkspace.shared.open(url)
- }
-
- @objc func openInFinder() async {
- await Shell.quiet("open '\(selectedSite!.absolutePath)'")
- }
-
- @objc func openInTerminal() async {
- await Shell.quiet("open -b com.apple.terminal '\(selectedSite!.absolutePath)'")
- }
-
- @objc func openWithEditor(sender: EditorMenuItem) async {
- guard let editor = sender.editor else { return }
- await editor.openDirectory(file: selectedSite!.absolutePath)
- }
-
@objc func isolateSite(sender: PhpMenuItem) {
let command = "sudo \(Paths.valet) isolate php@\(sender.version) --site '\(self.selectedSite!.name)' && exit;"
@@ -178,25 +212,11 @@ extension DomainListVC {
style: .critical,
onFirstButtonPressed: {
self.waitAndExecute {
- Task { await Shell.quiet("valet unproxy '\(proxy.domain)'") }
+ Task { await proxy.remove() }
} completion: {
Task { await self.reloadDomains() }
}
}
)
}
-
- private func performAction(command: String, beforeCellReload: @escaping () -> Void) {
- let rowToReload = tableView.selectedRow
-
- waitAndExecute {
- await Shell.quiet(command)
- } completion: { [self] in
- beforeCellReload()
- tableView.reloadData(forRowIndexes: [rowToReload], columnIndexes: [0, 1, 2, 3, 4])
- tableView.deselectRow(rowToReload)
- tableView.selectRowIndexes([rowToReload], byExtendingSelection: true)
- }
- }
-
}
diff --git a/phpmon/Domain/Integrations/Valet/Domains/ValetInteractor.swift b/phpmon/Domain/Integrations/Valet/Domains/ValetInteractor.swift
index 0e90616..318b942 100644
--- a/phpmon/Domain/Integrations/Valet/Domains/ValetInteractor.swift
+++ b/phpmon/Domain/Integrations/Valet/Domains/ValetInteractor.swift
@@ -8,6 +8,11 @@
import Foundation
+struct ValetInteractionError: Error {
+ /// The command the user should try (and failed).
+ var command: String
+}
+
#warning("ValetInteractor needs to be implemented and used")
class ValetInteractor {
public static func toggleSecure(site: ValetSite) async throws {
@@ -15,7 +20,33 @@ class ValetInteractor {
}
public static func toggleSecure(proxy: ValetProxy) async throws {
- // TODO
+ // Keep track of the original status (secure or not?)
+ let originalSecureStatus = proxy.secured
+
+ // Build the list of commands we will need to run
+ let commands: [String] = [
+ // Unproxy the given domain
+ "\(Paths.valet) unproxy \(proxy.domain)",
+ // Re-create the proxy (with the inverse secured status)
+ originalSecureStatus
+ ? "\(Paths.valet) proxy \(proxy.domain) \(proxy.target)"
+ : "\(Paths.valet) proxy \(proxy.domain) \(proxy.target) --secure"
+ ]
+
+ for command in commands {
+ await Shell.quiet(command)
+ }
+
+ // Check if the secured status has actually changed
+ proxy.determineSecured()
+ if proxy.secured == originalSecureStatus {
+ throw ValetInteractionError(
+ command: commands.joined(separator: " && ")
+ )
+ }
+
+ // Restart nginx to load the new configuration
+ await Actions.restartNginx()
}
public static func isolate(site: ValetSite, version: PhpVersionNumber) async throws {
@@ -25,4 +56,8 @@ class ValetInteractor {
public static func unlink(site: ValetSite) async throws {
// TODO
}
+
+ public static func remove(proxy: ValetProxy) async throws {
+ await Shell.quiet("valet unproxy '\(proxy.domain)'")
+ }
}
diff --git a/phpmon/Domain/Integrations/Valet/Proxies/ValetProxy.swift b/phpmon/Domain/Integrations/Valet/Proxies/ValetProxy.swift
index d0ea2ab..ce118e1 100644
--- a/phpmon/Domain/Integrations/Valet/Proxies/ValetProxy.swift
+++ b/phpmon/Domain/Integrations/Valet/Proxies/ValetProxy.swift
@@ -18,7 +18,7 @@ class ValetProxy: ValetListable {
self.domain = configuration.domain
self.tld = configuration.tld
self.target = configuration.proxy!
- self.secured = FileSystem.fileExists("~/.config/valet/Certificates/\(self.domain).\(self.tld).key")
+ self.determineSecured()
}
// MARK: - ValetListable Protocol
@@ -53,7 +53,15 @@ class ValetProxy: ValetListable {
// MARK: - Interactions
+ func determineSecured() {
+ self.secured = FileSystem.fileExists("~/.config/valet/Certificates/\(self.domain).\(self.tld).key")
+ }
+
func toggleSecure() async throws {
try await ValetInteractor.toggleSecure(proxy: self)
}
+
+ func remove() async {
+ try! await ValetInteractor.remove(proxy: self)
+ }
}