diff --git a/phpmon/Assets.xcassets/LockIcon.imageset/Contents.json b/phpmon/Assets.xcassets/GreenLock.imageset/Contents.json
similarity index 100%
rename from phpmon/Assets.xcassets/LockIcon.imageset/Contents.json
rename to phpmon/Assets.xcassets/GreenLock.imageset/Contents.json
diff --git a/phpmon/Assets.xcassets/LockIcon.imageset/GreenLock.svg b/phpmon/Assets.xcassets/GreenLock.imageset/GreenLock.svg
similarity index 100%
rename from phpmon/Assets.xcassets/LockIcon.imageset/GreenLock.svg
rename to phpmon/Assets.xcassets/GreenLock.imageset/GreenLock.svg
diff --git a/phpmon/Assets.xcassets/RedLock.imageset/RedLock.svg b/phpmon/Assets.xcassets/RedLock.imageset/RedLock.svg
index 66eeb55..cedd503 100644
--- a/phpmon/Assets.xcassets/RedLock.imageset/RedLock.svg
+++ b/phpmon/Assets.xcassets/RedLock.imageset/RedLock.svg
@@ -2,4 +2,12 @@
diff --git a/phpmon/Domain/Core/Base.lproj/Main.storyboard b/phpmon/Domain/Core/Base.lproj/Main.storyboard
index 1b11da0..730c2bc 100644
--- a/phpmon/Domain/Core/Base.lproj/Main.storyboard
+++ b/phpmon/Domain/Core/Base.lproj/Main.storyboard
@@ -313,18 +313,18 @@ Gw
-
-
+
+
-
+
-
+
-
+
@@ -368,10 +368,18 @@ Gw
-
+
-
-
+
+
+
+
+
+
+
+
+
+
@@ -381,26 +389,18 @@ Gw
-
-
-
-
-
-
-
-
+
-
-
+
+
-
-
+
@@ -437,6 +437,9 @@ Gw
+
+
+
@@ -444,6 +447,6 @@ Gw
-
+
diff --git a/phpmon/Domain/Integrations/Valet/Valet.swift b/phpmon/Domain/Integrations/Valet/Valet.swift
index 9941174..48cfe8f 100644
--- a/phpmon/Domain/Integrations/Valet/Valet.swift
+++ b/phpmon/Domain/Integrations/Valet/Valet.swift
@@ -15,8 +15,7 @@ class Valet {
var version: String
var config: Valet.Configuration
- var parkedSites: [Site] = []
- var linkedSites: [Site] = []
+ var sites: [Site] = []
init() {
self.version = Actions.valet("--version")
@@ -34,22 +33,21 @@ class Valet {
print("PHP Monitor should scan the following paths:")
print(self.config.paths)
- resolvePaths()
+ resolvePaths(tld: self.config.tld)
}
- private func resolvePaths() {
- self.linkedSites = []
- self.parkedSites = []
+ private func resolvePaths(tld: String) {
+ self.sites = []
for path in self.config.paths {
let entries = try! FileManager.default.contentsOfDirectory(atPath: path)
for entry in entries {
- self.resolvePath(entry, forPath: path)
+ self.resolvePath(entry, forPath: path, tld: tld)
}
}
}
- private func resolvePath(_ entry: String, forPath path: String) {
+ private func resolvePath(_ entry: String, forPath path: String, tld: String) {
let siteDir = path + "/" + entry
// See if the file is a symlink, if so, resolve it
@@ -59,11 +57,9 @@ class Valet {
let type = attrs[FileAttributeKey.type] as! FileAttributeType
if type == FileAttributeType.typeSymbolicLink {
- self.linkedSites.append(Site(aliasPath: siteDir))
+ self.sites.append(Site(aliasPath: siteDir, tld: tld))
} else if type == FileAttributeType.typeDirectory {
- self.parkedSites.append(Site(absolutePath: siteDir))
- } else {
- print("The item at: `\(siteDir)` was neither a symlink nor a directory. Skipping.")
+ self.sites.append(Site(absolutePath: siteDir, tld: tld))
}
}
@@ -74,19 +70,20 @@ class Valet {
var absolutePath: String
var aliasPath: String?
+ var secured: Bool
- init(absolutePath: String) {
+ init(absolutePath: String, tld: String) {
self.absolutePath = absolutePath
self.aliasPath = nil
self.name = URL(string: absolutePath)!.lastPathComponent
- self.detectSiteProperties()
+ self.secured = Shell.fileExists("~/.config/valet/Certificates/\(self.name).\(tld).key")
}
- convenience init(aliasPath: String) {
+ convenience init(aliasPath: String, tld: String) {
// Resolve the symlink
let absolutePath = try! FileManager.default
.destinationOfSymbolicLink(atPath: aliasPath)
- self.init(absolutePath: absolutePath)
+ self.init(absolutePath: absolutePath, tld: tld)
// TODO: Make sure the destination is a valid directory!
@@ -95,10 +92,9 @@ class Valet {
// Update the alias' path
self.aliasPath = aliasPath
- }
-
- private func detectSiteProperties() {
- // TODO: Determine additional information, like Composer status and PHP version?
+
+ // Make sure we check again, this time for the aliased file
+ self.secured = Shell.fileExists("~/.config/valet/Certificates/\(self.name).\(tld).key")
}
}
diff --git a/phpmon/Domain/SiteList/SiteListVC.swift b/phpmon/Domain/SiteList/SiteListVC.swift
index 069f329..0d5f1e7 100644
--- a/phpmon/Domain/SiteList/SiteListVC.swift
+++ b/phpmon/Domain/SiteList/SiteListVC.swift
@@ -12,6 +12,10 @@ import Carbon
class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
+ // MARK: - Outlets
+
+ @IBOutlet weak var tableView: NSTableView!
+
// MARK: - Display
public static func show(delegate: NSWindowDelegate? = nil) {
@@ -33,6 +37,13 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
// MARK: - Lifecycle
+ override func viewDidLoad() {
+ let menu = NSMenu()
+ // menu.addItem(withTitle: "Secure", action: #selector(self.action), keyEquivalent: "L")
+ menu.addItem(withTitle: "Open in Browser...", action: #selector(self.openInBrowser), keyEquivalent: "O")
+ tableView.menu = menu
+ }
+
override func viewWillAppear() {
}
@@ -44,23 +55,45 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
// MARK: - Table View
func numberOfRows(in tableView: NSTableView) -> Int {
- return Valet.shared.linkedSites.count
+ return Valet.shared.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 }
- let item = Valet.shared.linkedSites[row]
+ let item = Valet.shared.sites[row]
+ /// Make sure to show the TLD
userCell.labelSiteName.stringValue = "\(item.name).\(Valet.shared.config.tld)"
- userCell.labelPathName.stringValue = item.absolutePath
- userCell.labelSiteType.isHidden = true
- userCell.labelPhpVersion.isHidden = true
+ /// 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.labelSiteType.stringValue = item.aliasPath == nil
+ ? "Parked Site"
+ : "Linked Site"
+
+ /// Show the green or red lock based on whether the site was secured
+ userCell.imageViewLock.image = NSImage(named: item.secured ? "GreenLock" : "RedLock")
+
+ /// TODO: Load the correct PHP version (not determined as of yet)
+ userCell.labelPhpVersion.stringValue = "PHP 8.0"
return userCell
}
-
+
+ @objc public func openInBrowser() {
+ if self.tableView.selectedRow == -1 {
+ return
+ }
+
+ let site = Valet.shared.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)!)
+ }
// MARK: - Deinitialization
diff --git a/phpmon/Domain/SiteList/SiteListWC.swift b/phpmon/Domain/SiteList/SiteListWC.swift
index 2a3122a..cefe3ae 100644
--- a/phpmon/Domain/SiteList/SiteListWC.swift
+++ b/phpmon/Domain/SiteList/SiteListWC.swift
@@ -14,4 +14,18 @@ class SiteListWC: NSWindowController {
super.windowDidLoad()
}
+ /**
+ Allow users to close the window using Cmd-W, a shortcut I definitely use a lot.
+ */
+ override func keyDown(with event: NSEvent) {
+ if event.modifierFlags.contains(.command) {
+ switch event.charactersIgnoringModifiers! {
+ case "w":
+ self.window?.close()
+ default:
+ break
+ }
+ }
+ }
+
}