From 29d34a6b62b32f1d31ffd7fb92d9a78ce1e4a774 Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Sun, 5 Dec 2021 15:08:43 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=8C=20Polish=20for=20v5.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- phpmon/Domain/Core/App+GlobalHotkey.swift | 6 +- phpmon/Domain/Core/App.swift | 2 +- phpmon/Domain/Core/Startup.swift | 2 +- phpmon/Domain/Helpers/Alert.swift | 8 +- .../Domain/Helpers/PMWindowController.swift | 4 +- .../Homebrew/HomebrewDiagnostics.swift | 4 +- phpmon/Domain/Integrations/Valet/Valet.swift | 22 +- phpmon/Domain/PHP/ActivePhpInstallation.swift | 14 +- phpmon/Domain/Preferences/Preferences.swift | 2 +- phpmon/Domain/Preferences/PrefsVC.swift | 2 +- phpmon/Domain/Preferences/PrefsWC.swift | 2 +- phpmon/Domain/SiteList/SiteListCell.swift | 24 ++ phpmon/Domain/SiteList/SiteListVC.swift | 315 +++++++++--------- phpmon/Domain/Terminal/Shell.swift | 23 +- phpmon/Localizable.strings | 8 +- 15 files changed, 238 insertions(+), 200 deletions(-) diff --git a/phpmon/Domain/Core/App+GlobalHotkey.swift b/phpmon/Domain/Core/App+GlobalHotkey.swift index 3b6addb..f1b730f 100644 --- a/phpmon/Domain/Core/App+GlobalHotkey.swift +++ b/phpmon/Domain/Core/App+GlobalHotkey.swift @@ -27,11 +27,11 @@ extension App { // Make sure we can parse the JSON into the desired format guard let keybindPref = GlobalKeybindPreference.fromJson(hotkey) else { print("No global hotkey loaded, could not be parsed!") - self.shortcutHotkey = nil + shortcutHotkey = nil return } - self.shortcutHotkey = HotKey(keyCombo: KeyCombo( + shortcutHotkey = HotKey(keyCombo: KeyCombo( carbonKeyCode: keybindPref.keyCode, carbonModifiers: keybindPref.carbonFlags )) @@ -42,7 +42,7 @@ extension App { (opens the menu). */ func setupGlobalHotkeyListener() { - guard let hotkey = self.shortcutHotkey else { + guard let hotkey = shortcutHotkey else { return } diff --git a/phpmon/Domain/Core/App.swift b/phpmon/Domain/Core/App.swift index b3786f0..c1cbf80 100644 --- a/phpmon/Domain/Core/App.swift +++ b/phpmon/Domain/Core/App.swift @@ -90,7 +90,7 @@ class App { */ var shortcutHotkey: HotKey? = nil { didSet { - self.setupGlobalHotkeyListener() + setupGlobalHotkeyListener() } } diff --git a/phpmon/Domain/Core/Startup.swift b/phpmon/Domain/Core/Startup.swift index 42ebfa7..b42c8ab 100644 --- a/phpmon/Domain/Core/Startup.swift +++ b/phpmon/Domain/Core/Startup.swift @@ -26,7 +26,7 @@ class Startup { performEnvironmentCheck( !Shell.fileExists("\(Paths.binPath)/php"), messageText: "startup.errors.php_binary.title".localized, - informativeText: "startup.errors.php_binary_desc".localized, + informativeText: "startup.errors.php_binary.desc".localized, breaking: true ) diff --git a/phpmon/Domain/Helpers/Alert.swift b/phpmon/Domain/Helpers/Alert.swift index 735abad..afe056c 100644 --- a/phpmon/Domain/Helpers/Alert.swift +++ b/phpmon/Domain/Helpers/Alert.swift @@ -28,7 +28,13 @@ class Alert { } public static func notify(message: String, info: String, style: NSAlert.Style = .informational) { - _ = self.present(messageText: message, informativeText: info, buttonTitle: "OK", secondButtonTitle: "", style: style) + _ = present( + messageText: message, + informativeText: info, + buttonTitle: "OK", + secondButtonTitle: "", + style: style + ) } } diff --git a/phpmon/Domain/Helpers/PMWindowController.swift b/phpmon/Domain/Helpers/PMWindowController.swift index 9d41965..5e5a62b 100644 --- a/phpmon/Domain/Helpers/PMWindowController.swift +++ b/phpmon/Domain/Helpers/PMWindowController.swift @@ -22,11 +22,11 @@ class PMWindowController: NSWindowController, NSWindowDelegate { override func showWindow(_ sender: Any?) { super.showWindow(sender) - App.shared.register(window: self.windowName) + App.shared.register(window: windowName) } func windowWillClose(_ notification: Notification) { - App.shared.remove(window: self.windowName) + App.shared.remove(window: windowName) } deinit { diff --git a/phpmon/Domain/Integrations/Homebrew/HomebrewDiagnostics.swift b/phpmon/Domain/Integrations/Homebrew/HomebrewDiagnostics.swift index 7c14556..fd327a8 100644 --- a/phpmon/Domain/Integrations/Homebrew/HomebrewDiagnostics.swift +++ b/phpmon/Domain/Integrations/Homebrew/HomebrewDiagnostics.swift @@ -18,8 +18,8 @@ class HomebrewDiagnostics { var errors: [HomebrewDiagnostics.Errors] = [] init() { - if self.determineAliasConflicts() { - self.errors.append(.aliasConflict) + if determineAliasConflicts() { + errors.append(.aliasConflict) } } diff --git a/phpmon/Domain/Integrations/Valet/Valet.swift b/phpmon/Domain/Integrations/Valet/Valet.swift index cea303d..5039a97 100644 --- a/phpmon/Domain/Integrations/Valet/Valet.swift +++ b/phpmon/Domain/Integrations/Valet/Valet.swift @@ -18,35 +18,35 @@ class Valet { var sites: [Site] = [] init() { - self.version = Actions.valet("--version") + version = Actions.valet("--version") .replacingOccurrences(of: "Laravel Valet ", with: "") .trimmingCharacters(in: .whitespacesAndNewlines) let file = FileManager.default.homeDirectoryForCurrentUser .appendingPathComponent(".config/valet/config.json") - self.config = try! JSONDecoder().decode( + config = try! JSONDecoder().decode( Valet.Configuration.self, from: try! String(contentsOf: file, encoding: .utf8).data(using: .utf8)! ) print("PHP Monitor should scan the following paths:") - print(self.config.paths) + print(config.paths) - resolvePaths(tld: self.config.tld) + resolvePaths(tld: config.tld) } public func reloadSites() { - resolvePaths(tld: self.config.tld) + resolvePaths(tld: config.tld) } private func resolvePaths(tld: String) { - self.sites = [] + sites = [] - for path in self.config.paths { + for path in config.paths { let entries = try! FileManager.default.contentsOfDirectory(atPath: path) for entry in entries { - self.resolvePath(entry, forPath: path, tld: tld) + resolvePath(entry, forPath: path, tld: tld) } } } @@ -61,9 +61,9 @@ class Valet { let type = attrs[FileAttributeKey.type] as! FileAttributeType if type == FileAttributeType.typeSymbolicLink { - self.sites.append(Site(aliasPath: siteDir, tld: tld)) + sites.append(Site(aliasPath: siteDir, tld: tld)) } else if type == FileAttributeType.typeDirectory { - self.sites.append(Site(absolutePath: siteDir, tld: tld)) + sites.append(Site(absolutePath: siteDir, tld: tld)) } } @@ -99,7 +99,7 @@ class Valet { } public func determineSecured(_ tld: String) { - self.secured = Shell.fileExists("~/.config/valet/Certificates/\(self.name!).\(tld).key") + secured = Shell.fileExists("~/.config/valet/Certificates/\(self.name!).\(tld).key") } public func determineDriver() { diff --git a/phpmon/Domain/PHP/ActivePhpInstallation.swift b/phpmon/Domain/PHP/ActivePhpInstallation.swift index a638057..08aa4b5 100644 --- a/phpmon/Domain/PHP/ActivePhpInstallation.swift +++ b/phpmon/Domain/PHP/ActivePhpInstallation.swift @@ -32,7 +32,7 @@ class ActivePhpInstallation { init() { // Show information about the current version - self.getVersion() + getVersion() // If an error occurred, exit early if (version.error) { @@ -47,9 +47,9 @@ class ActivePhpInstallation { // Get configuration values configuration = Configuration( - memory_limit: self.getByteCount(key: "memory_limit"), - upload_max_filesize: self.getByteCount(key: "upload_max_filesize"), - post_max_size: self.getByteCount(key: "post_max_size") + memory_limit: getByteCount(key: "memory_limit"), + upload_max_filesize: getByteCount(key: "upload_max_filesize"), + post_max_size: getByteCount(key: "post_max_size") ) // Return a list of .ini files parsed after php.ini @@ -60,9 +60,9 @@ class ActivePhpInstallation { // See if any extensions are present in said .ini files paths.forEach { (iniFilePath) in - let extensions = PhpExtension.load(from: URL(fileURLWithPath: iniFilePath)) - if extensions.count > 0 { - self.extensions.append(contentsOf: extensions) + let exts = PhpExtension.load(from: URL(fileURLWithPath: iniFilePath)) + if exts.count > 0 { + extensions.append(contentsOf: exts) } } } diff --git a/phpmon/Domain/Preferences/Preferences.swift b/phpmon/Domain/Preferences/Preferences.swift index 72b94d8..398368b 100644 --- a/phpmon/Domain/Preferences/Preferences.swift +++ b/phpmon/Domain/Preferences/Preferences.swift @@ -26,7 +26,7 @@ class Preferences { public init() { Preferences.handleFirstTimeLaunch() - self.cachedPreferences = Self.cache() + cachedPreferences = Self.cache() } // MARK: - First Time Run diff --git a/phpmon/Domain/Preferences/PrefsVC.swift b/phpmon/Domain/Preferences/PrefsVC.swift index 9a4de95..6448f61 100644 --- a/phpmon/Domain/Preferences/PrefsVC.swift +++ b/phpmon/Domain/Preferences/PrefsVC.swift @@ -75,7 +75,7 @@ class PrefsVC: NSViewController { } override func viewWillDisappear() { - if self.listeningForGlobalHotkey { + if listeningForGlobalHotkey { listeningForGlobalHotkey = false } } diff --git a/phpmon/Domain/Preferences/PrefsWC.swift b/phpmon/Domain/Preferences/PrefsWC.swift index af1a36e..b04199f 100644 --- a/phpmon/Domain/Preferences/PrefsWC.swift +++ b/phpmon/Domain/Preferences/PrefsWC.swift @@ -32,7 +32,7 @@ class PrefsWC: PMWindowController { override func keyDown(with event: NSEvent) { super.keyDown(with: event) - if let vc = self.contentViewController as? PrefsVC { + if let vc = contentViewController as? PrefsVC { if vc.listeningForGlobalHotkey { if event.keyCode == Keys.Escape || event.keyCode == Keys.Space { print("A blacklisted key was pressed, canceling listen") diff --git a/phpmon/Domain/SiteList/SiteListCell.swift b/phpmon/Domain/SiteList/SiteListCell.swift index 827e0ab..32f3464 100644 --- a/phpmon/Domain/SiteList/SiteListCell.swift +++ b/phpmon/Domain/SiteList/SiteListCell.swift @@ -22,4 +22,28 @@ class SiteListCell: NSTableCellView override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) } + + func populateCell(with site: Valet.Site) { + // Make sure to show the TLD + labelSiteName.stringValue = "\(site.name!).\(Valet.shared.config.tld)" + + // Show the absolute path, except make sure to replace the /Users/username segment with ~ for readability + labelPathName.stringValue = site.absolutePath + .replacingOccurrences(of: "/Users/\(Paths.whoami)", with: "~") + + // If the `aliasPath` is nil, we're dealing with a parked site (otherwise: linked). + imageViewType.image = NSImage( + named: site.aliasPath == nil + ? "IconParked" + : "IconLinked" + ) + imageViewType.contentTintColor = NSColor.tertiaryLabelColor + + // Show the green or red lock based on whether the site was secured + imageViewLock.contentTintColor = site.secured ? NSColor.systemGreen + : NSColor.red + + // Show the current driver + labelDriver.stringValue = site.driver + } } diff --git a/phpmon/Domain/SiteList/SiteListVC.swift b/phpmon/Domain/SiteList/SiteListVC.swift index d20d4e7..2405add 100644 --- a/phpmon/Domain/SiteList/SiteListVC.swift +++ b/phpmon/Domain/SiteList/SiteListVC.swift @@ -23,6 +23,15 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource { var editorAvailability: [String] = [] var lastSearchedFor = "" + // MARK: - Helper Variables + + var selectedSite: Valet.Site? { + if tableView.selectedRow == -1 { + return nil + } + return sites[tableView.selectedRow] + } + // MARK: - Display public static func create(delegate: NSWindowDelegate?) { @@ -56,103 +65,196 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource { // MARK: - Lifecycle override func viewDidLoad() { - if (Shell.fileExists("/usr/local/bin/code")) { - self.editorAvailability.append("vscode") + determineEditorAvailability() + sites = Valet.shared.sites + setUINotBusy() + } + + // MARK: - Async Operations + + /** + Disables the UI so the user cannot interact with it. + Also shows a spinner to indicate that we're busy. + */ + private func setUIBusy() { + progressIndicator.startAnimation(nil) + tableView.alphaValue = 0.3 + tableView.isEnabled = false + } + + /** + Re-enables the UI so the user can interact with it. + */ + private func setUINotBusy() { + progressIndicator.stopAnimation(nil) + tableView.alphaValue = 1.0 + tableView.isEnabled = true + } + + /** + Executes a specific callback and fires the completion callback, + while updating the UI as required. As long as the completion callback + does not fire, the app is presumed to be busy and the UI reflects this. + + - Parameter execute: Callback of the work that needs to happen. + - Parameter completion: Callback that is fired when the work is done. + */ + private func waitAndExecute(_ execute: @escaping () -> Void, completion: @escaping () -> Void = {}) + { + setUIBusy() + DispatchQueue.global(qos: .userInitiated).async { [unowned self] in + execute() + + DispatchQueue.main.async { [self] in + completion() + setUINotBusy() + } } - - if (Shell.fileExists("/Applications/PhpStorm.app/Contents/Info.plist")) { - self.editorAvailability.append("phpstorm") - } - - self.sites = Valet.shared.sites - self.progressIndicator.stopAnimation(nil) } // MARK: - Site Data Loading func reloadSites() { - // Start spinner and reset view (no items) - self.progressIndicator.startAnimation(nil) - self.tableView.alphaValue = 0.3 - self.tableView.isEnabled = false - - DispatchQueue.global(qos: .userInitiated).async { [unowned self] in - // Reload site information + waitAndExecute { Valet.shared.reloadSites() - - DispatchQueue.main.async { [self] in - // Update the site list - self.sites = Valet.shared.sites - - // Stop spinner - self.progressIndicator.stopAnimation(nil) - self.tableView.alphaValue = 1.0 - self.tableView.isEnabled = true - - // Re-apply any existing search - self.searchedFor(text: lastSearchedFor) - } + } completion: { [self] in + sites = Valet.shared.sites + searchedFor(text: lastSearchedFor) } } - // MARK: - Table View + // MARK: - Table View Delegate func numberOfRows(in tableView: NSTableView) -> Int { - return self.sites.count + return sites.count } func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { - guard let userCell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "siteItem"), owner: self) as? SiteListCell else { return nil } + guard let userCell = tableView.makeView( + withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "siteItem"), owner: self + ) as? SiteListCell else { return nil } - let item = self.sites[row] - - /// Make sure to show the TLD - userCell.labelSiteName.stringValue = "\(item.name!).\(Valet.shared.config.tld)" - - /// Show the absolute path, except make sure to replace the /Users/username segment with ~ for readability - userCell.labelPathName.stringValue = item.absolutePath - .replacingOccurrences(of: "/Users/\(Paths.whoami)", with: "~") - - /// If the `aliasPath` is nil, we're dealing with a parked site. Otherwise, it's a link that was explicitly created. - userCell.imageViewType.image = NSImage( - named: item.aliasPath == nil - ? "IconParked" - : "IconLinked" - ) - userCell.imageViewType.contentTintColor = NSColor.tertiaryLabelColor - - /// Show the green or red lock based on whether the site was secured - userCell.imageViewLock.contentTintColor = item.secured ? NSColor.systemGreen - : NSColor.red - - /// Show the current driver - userCell.labelDriver.stringValue = item.driver + userCell.populateCell(with: sites[row]) return userCell } func tableViewSelectionDidChange(_ notification: Notification) { + reloadContextMenu() + } + + // MARK: Secure & Unsecure + + @objc public func toggleSecure() { + let rowToReload = tableView.selectedRow + let originalSecureStatus = selectedSite!.secured + let action = selectedSite!.secured ? "unsecure" : "secure" + let selectedSite = selectedSite! + let command = "cd \(selectedSite.absolutePath!) && sudo \(Paths.valet) \(action) && exit;" + + waitAndExecute { + Shell.run(command, requiresPath: true) + } completion: { [self] in + selectedSite.determineSecured(Valet.shared.config.tld) + if selectedSite.secured == originalSecureStatus { + Alert.notify( + message: "site_list.alerts_status_changed.title".localized, + info: "\("site_list.alerts_status_changed.desc".localized) `\(command)`") + } else { + let newState = selectedSite.secured ? "secured" : "unsecured" + LocalNotification.send( + title: "site_list.alerts_status_changed.title".localized, + subtitle: "site_list.alerts_status_changed.desc" + .localized + .replacingOccurrences(of: "{@1}", with: "\(selectedSite.name!).\(Valet.shared.config.tld)") + .replacingOccurrences(of: "{@2}", with: newState) + ) + } + + tableView.reloadData(forRowIndexes: [rowToReload], columnIndexes: [0]) + tableView.deselectRow(rowToReload) + tableView.selectRowIndexes([rowToReload], byExtendingSelection: true) + } + } + + // MARK: Open with IDE / Editor + + /** + Find out which editors are available on the user’s system. + Currently only PHPStorm and Visual Studio Code are detected. + */ + private func determineEditorAvailability() { + if (Shell.fileExists("/usr/local/bin/code")) { + editorAvailability.append("vscode") + } + + if (Shell.fileExists("/Applications/PhpStorm.app/Contents/Info.plist")) { + editorAvailability.append("phpstorm") + } + } + + @objc public func openWithPhpStorm() { + Shell.run("open -a /Applications/PhpStorm.app \(selectedSite!.absolutePath!)") + } + + @objc public func openWithVSCode() { + Shell.run("/usr/local/bin/code \(selectedSite!.absolutePath!)") + } + + // MARK: Open in Browser & Finder + + @objc public func openInBrowser() { + let prefix = selectedSite!.secured ? "https://" : "http://" + let url = "\(prefix)\(selectedSite!.name!).\(Valet.shared.config.tld)" + NSWorkspace.shared.open(URL(string: url)!) + } + + @objc public func openInFinder() { + Shell.run("open \(selectedSite!.absolutePath!)") + } + + // MARK: - (Search) Text Field Delegate + + func searchedFor(text: String) { + lastSearchedFor = text + + let searchString = text.lowercased() + + if searchString.isEmpty { + sites = Valet.shared.sites + tableView.reloadData() + return + } + + sites = Valet.shared.sites.filter({ site in + return site.name.lowercased().contains(searchString) + }) + + tableView.reloadData() + } + + // MARK: - Context Menu + + private func reloadContextMenu() { let menu = NSMenu() - if self.tableView.selectedRow == -1 { + guard let site = selectedSite else { tableView.menu = nil return } - let site = self.sites[self.tableView.selectedRow] - menu.addItem( withTitle: site.secured - ? "site_list.unsecure".localized - : "site_list.secure".localized, + ? "site_list.unsecure".localized + : "site_list.secure".localized, action: #selector(toggleSecure), keyEquivalent: "L" ) - if (self.editorAvailability.count > 0) { + if (editorAvailability.count > 0) { menu.addItem(NSMenuItem.separator()) - if self.editorAvailability.contains("vscode") { + if editorAvailability.contains("vscode") { menu.addItem( withTitle: "site_list.open_with_vs_code".localized, action: #selector(self.openWithVSCode), @@ -181,96 +283,9 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource { action: #selector(self.openInBrowser), keyEquivalent: "O" ) + tableView.menu = menu } - - // MARK: Secure / unsecure - - @objc public func toggleSecure() { - let rowToReload = self.tableView.selectedRow - let site = self.sites[self.tableView.selectedRow] - let previous = site.secured - let action = site.secured ? "unsecure" : "secure" - - self.progressIndicator.startAnimation(nil) - self.tableView.alphaValue = 0.3 - self.tableView.isEnabled = false - - DispatchQueue.global(qos: .userInitiated).async { [unowned self] in - let command = "cd \(site.absolutePath!) && sudo \(Paths.valet) \(action) && exit;" - let _ = Shell.pipe(command, requiresPath: true) - - site.determineSecured(Valet.shared.config.tld) - - DispatchQueue.main.async { [self] in - if site.secured == previous { - Alert.notify( - message: "SSL status not changed", - info: "Something went wrong. Try running the command in your terminal manually: `\(command)`") - } else { - let newState = site.secured ? "secured" : "unsecured" - LocalNotification.send( - title: "SSL status changed", - subtitle: "The domain '\(site.name!).\(Valet.shared.config.tld)' is now \(newState)." - ) - } - - progressIndicator.stopAnimation(nil) - self.tableView.alphaValue = 1 - self.tableView.isEnabled = true - - tableView.reloadData(forRowIndexes: [rowToReload], columnIndexes: [0]) - tableView.deselectRow(rowToReload) - tableView.selectRowIndexes([rowToReload], byExtendingSelection: true) - } - } - } - - // MARK: Open with IDE / Editor - - @objc public func openWithPhpStorm() { - let site = self.sites[self.tableView.selectedRow] - Shell.run("open -a /Applications/PhpStorm.app \(site.absolutePath!)") - } - - @objc public func openWithVSCode() { - let site = self.sites[self.tableView.selectedRow] - Shell.run("/usr/local/bin/code \(site.absolutePath!)") - } - - // MARK: Open in Browser & Finder - - @objc public func openInBrowser() { - let site = self.sites[self.tableView.selectedRow] - let prefix = site.secured ? "https://" : "http://" - let url = "\(prefix)\(site.name!).\(Valet.shared.config.tld)" - NSWorkspace.shared.open(URL(string: url)!) - } - - @objc public func openInFinder() { - let site = self.sites[self.tableView.selectedRow] - Shell.run("open \(site.absolutePath!)") - } - - // MARK: - (Search) Text Field Delegate - - func searchedFor(text: String) { - self.lastSearchedFor = text - - let searchString = text.lowercased() - - if searchString.isEmpty { - self.sites = Valet.shared.sites - tableView.reloadData() - return - } - - self.sites = Valet.shared.sites.filter({ site in - return site.name.lowercased().contains(searchString) - }) - - tableView.reloadData() - } // MARK: - Deinitialization diff --git a/phpmon/Domain/Terminal/Shell.swift b/phpmon/Domain/Terminal/Shell.swift index a1df115..2bc7c25 100644 --- a/phpmon/Domain/Terminal/Shell.swift +++ b/phpmon/Domain/Terminal/Shell.swift @@ -15,7 +15,7 @@ class Shell { _ command: String, requiresPath: Bool = false ) { - Shell.user.run(command) + Shell.user.run(command, requiresPath: requiresPath) } public static func pipe( @@ -27,23 +27,10 @@ class Shell { // MARK: - Singleton - var shell: String - - init() { - // Determine if we're using macOS Catalina or newer (that support /bin/zsh as default shell) - let at_least_10_15 = ProcessInfo.processInfo.isOperatingSystemAtLeast( - .init(majorVersion: 10, minorVersion: 15, patchVersion: 0)) - - // If macOS Mojave is being used, we'll default to /bin/bash - shell = at_least_10_15 - ? "/bin/sh" - : "/bin/bash" - - print(at_least_10_15 - ? "Detected recent macOS (> 10.15): defaulting to /bin/sh" - : "Detected older macOS (< 10.15): defaulting to /bin/bash" - ) - } + /** + We now require macOS 11, so no need to detect which terminal to use. + */ + var shell: String = "/bin/sh" /** Singleton to access a user shell (with --login) diff --git a/phpmon/Localizable.strings b/phpmon/Localizable.strings index 698b3ad..ae82b11 100644 --- a/phpmon/Localizable.strings +++ b/phpmon/Localizable.strings @@ -53,6 +53,12 @@ "site_list.title" = "Domains"; "site_list.subtitle" = "Linked & Parked"; +"site_list.alerts_status_changed.title" = "SSL Status Not Changed"; +"site_list.alerts_status_changed.desc" = "Something went wrong. Try running the command in your terminal manually:"; + +"site_list.alerts_status_changed.title" = "SSL Status Changed"; +"site_list.alerts_status_changed.desc" = "The domain '{@1}' is now {@2}."; + // SITE LIST ACTIONS "site_list.secure" = "Secure"; @@ -127,7 +133,7 @@ /// 1. PHP binary not found "startup.errors.php_binary.title" = "PHP is not correctly installed"; -"startup.errors.php_binary_desc" = "You must install PHP via brew. Try running `which php` in Terminal, it should return `/usr/local/bin/php` (or `/opt/homebrew/bin/php`). The app will not work correctly until you resolve this issue. (Usually `brew link php` resolves this issue.)"; +"startup.errors.php_binary.desc" = "You must install PHP via brew. Try running `which php` in Terminal, it should return `/usr/local/bin/php` (or `/opt/homebrew/bin/php`). The app will not work correctly until you resolve this issue. (Usually `brew link php` resolves this issue.)"; /// 2. PHP not found in /usr/local/opt or /opt/homebrew/opt "startup.errors.php_opt.title" = "PHP is not correctly installed";