1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-08-07 12:00:09 +02:00
Files
app/phpmon/Modules/Domain List/UI/DomainListVC+Actions.swift

286 lines
9.5 KiB
Swift

//
// DomainListVC+Actions.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 23/12/2021.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
import Cocoa
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: "generic.ok".localized)
.show()
return
}
NSWorkspace.shared.open(url)
}
@objc func openInFinder() {
Task { return await Shell.quiet("open '\(selectedSite!.absolutePath)'") }
}
@objc func openInTerminal() {
Task { await Shell.quiet("open -b com.apple.terminal '\(selectedSite!.absolutePath)'") }
}
@objc func openWithEditor(sender: EditorMenuItem) {
guard let editor = sender.editor else { return }
editor.openDirectory(file: selectedSite!.absolutePath)
}
// MARK: - UI interaction
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)
}
}
private func reloadSelectedRow() {
tableView.reloadData(forRowIndexes: [tableView.selectedRow], columnIndexes: [0, 1, 2, 3, 4])
tableView.deselectRow(tableView.selectedRow)
tableView.selectRowIndexes([tableView.selectedRow], byExtendingSelection: true)
}
// MARK: - Interactions with `valet` or terminal
@objc func toggleSecure() {
if selected is ValetSite {
Task { await toggleSecure(site: selected as! ValetSite) }
}
if selected is ValetProxy {
Task { await toggleSecure(proxy: selected as! ValetProxy) }
}
}
func toggleSecure(proxy: ValetProxy) async {
waitAndExecute {
do {
// Recreate proxy as secure or unsecured proxy
try await proxy.toggleSecure()
// Send a notification about the new status (if applicable)
self.notifyAboutModifiedSecureStatus(domain: proxy.domain, secured: proxy.secured)
// Reload the UI (do this last so we don't invalidate the proxy)
self.reloadSelectedRow()
} catch {
// Notify the user about a failed command
let error = error as! ValetInteractionError
self.notifyAboutFailedSecureStatus(command: error.command)
}
}
}
func toggleSecure(site: ValetSite) async {
waitAndExecute {
do {
// Instruct Valet to secure or unsecure a site
try await site.toggleSecure()
// Send a notification about the new status (if applicable)
self.notifyAboutModifiedSecureStatus(domain: site.name, secured: site.secured)
// Reload the UI (do this last so we don't invalidate the site)
self.reloadSelectedRow()
} catch {
// Notify the user about a failed command
let error = error as! ValetInteractionError
self.notifyAboutFailedSecureStatus(command: error.command)
}
}
}
@objc func toggleExtension(sender: ExtensionMenuItem) {
Task {
self.setUIBusy()
await sender.phpExtension?.toggle()
if Preferences.isEnabled(.autoServiceRestartAfterExtensionToggle) {
await Actions.restartPhpFpm()
}
reloadContextMenu()
self.setUINotBusy()
}
}
public func isolateSite(site: ValetSite, version: String) {
waitAndExecute {
do {
// Instruct Valet to isolate a given PHP version
try await site.isolate(version: version)
// Reload the UI if it's the same site
if self.selectedSite?.absolutePath == site.absolutePath {
self.reloadSelectedRow()
} else {
await self.reloadDomains()
}
} catch {
// Notify the user about a failed command
let error = error as! ValetInteractionError
self.notifyAboutFailedSiteIsolation(command: error.command)
}
}
}
@objc func isolateSiteViaMenuItem(sender: PhpMenuItem) {
guard let site = selectedSite else {
return
}
self.isolateSite(site: site, version: sender.version)
}
@objc func removeIsolatedSiteViaMenuItem() {
guard let site = selectedSite else {
return
}
waitAndExecute {
do {
// Instruct Valet to remove isolation
try await site.unisolate()
// Reload the UI
self.reloadSelectedRow()
} catch {
// Notify the user about a failed command
let error = error as! ValetInteractionError
self.notifyAboutFailedSiteIsolation(command: error.command)
}
}
}
@objc func unlinkSite() {
guard let site = selectedSite else {
return
}
if site.aliasPath == nil {
return
}
Alert.confirm(
onWindow: view.window!,
messageText: "domain_list.confirm_unlink".localized(site.name),
informativeText: "domain_list.confirm_unlink_desc".localized,
buttonTitle: "domain_list.unlink".localized,
secondButtonTitle: "Cancel",
style: .critical,
onFirstButtonPressed: {
self.waitAndExecute {
await site.unlink()
await self.reloadDomainsWithoutUI()
}
}
)
}
@objc func removeProxy() {
guard let proxy = selectedProxy else {
return
}
Alert.confirm(
onWindow: view.window!,
messageText: "domain_list.confirm_unproxy".localized("\(proxy.domain).\(proxy.tld)"),
informativeText: "domain_list.confirm_unproxy_desc".localized,
buttonTitle: "domain_list.unproxy".localized,
secondButtonTitle: "Cancel",
style: .critical,
onFirstButtonPressed: {
self.waitAndExecute {
await proxy.remove()
await self.reloadDomainsWithoutUI()
}
}
)
}
@objc func useInTerminal() {
guard let site = selectedSite else {
return
}
guard let version = site.isolatedPhpVersion?.versionNumber else {
return
}
self.notifyAboutUsingIsolatedPhpVersionInTerminal(version: version)
}
// MARK: - Alerts & Modals
private func notifyAboutModifiedSecureStatus(domain: String, secured: Bool) {
LocalNotification.send(
title: "domain_list.alerts_status_changed.title".localized,
subtitle: "domain_list.alerts_status_changed.desc"
.localized(
// 1. The domain that was secured is listed
"\(domain).\(Valet.shared.config.tld)",
// 2. What the domain is is listed (secure / unsecure)
secured
? "domain_list.alerts_status_secure".localized
: "domain_list.alerts_status_unsecure".localized
),
preference: .notifyAboutSecureToggle
)
}
private func notifyAboutUsingIsolatedPhpVersionInTerminal(version: VersionNumber) {
BetterAlert()
.withInformation(
title: "domain_list.alerts_isolated_php_terminal.title".localized(version.short),
subtitle: "domain_list.alerts_isolated_php_terminal.subtitle".localized(
"\(version.major)\(version.minor)",
version.short
),
description: "domain_list.alerts_isolated_php_terminal.desc".localized
)
.withPrimary(text: "generic.ok".localized)
.show()
}
private func notifyAboutFailedSecureStatus(command: String) {
BetterAlert()
.withInformation(
title: "domain_list.alerts_status_not_changed.title".localized,
subtitle: "domain_list.alerts_status_not_changed.desc".localized(command)
)
.withPrimary(text: "generic.ok".localized)
.show()
}
private func notifyAboutFailedSiteIsolation(command: String) {
BetterAlert()
.withInformation(
title: "domain_list.alerts_isolation_failed.title".localized,
subtitle: "domain_list.alerts_isolation_failed.subtitle".localized,
description: "domain_list.alerts_isolation_failed.desc".localized(command)
)
.withPrimary(text: "generic.ok".localized)
.show()
}
}