1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-11-05 20:40:05 +01:00

Mark domain as favorite (UI only)

Please note that this functionality is currently not persistent.
As such, reloading the domain list will reset any changes you have made.
This commit is contained in:
2024-08-25 13:35:27 +02:00
parent 0c320074da
commit 5c9c51f580
9 changed files with 67 additions and 11 deletions

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> <document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies> <dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22690"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22690"/>
<capability name="Image references" minToolsVersion="12.0"/> <capability name="Image references" minToolsVersion="12.0"/>
<capability name="Named colors" minToolsVersion="9.0"/> <capability name="Named colors" minToolsVersion="9.0"/>
@@ -825,11 +826,18 @@ Gw
<rect key="frame" x="0.0" y="0.0" width="626" height="309"/> <rect key="frame" x="0.0" y="0.0" width="626" height="309"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<progressIndicator maxValue="100" displayedWhenStopped="NO" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="ZiS-Gq-TLQ">
<rect key="frame" x="298" y="150" width="30" height="30"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="XK3-AR-Oc0"/>
<constraint firstAttribute="height" constant="30" id="lfW-dB-Eu3"/>
</constraints>
</progressIndicator>
<scrollView borderType="none" horizontalLineScroll="54" horizontalPageScroll="10" verticalLineScroll="54" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p0j-eB-I2i"> <scrollView borderType="none" horizontalLineScroll="54" horizontalPageScroll="10" verticalLineScroll="54" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p0j-eB-I2i">
<rect key="frame" x="0.0" y="0.0" width="626" height="309"/> <rect key="frame" x="0.0" y="0.0" width="626" height="309"/>
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" id="6IL-DW-37w"> <clipView key="contentView" ambiguous="YES" drawsBackground="NO" id="6IL-DW-37w">
<rect key="frame" x="0.0" y="0.0" width="611" height="294"/> <rect key="frame" x="0.0" y="0.0" width="611" height="294"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" multipleSelection="NO" autosaveName="phpmon-sitelist-columns" rowHeight="54" headerView="xUg-Mq-OSh" viewBased="YES" id="cp3-34-pQj" customClass="PMTableView" customModule="PHP_Monitor" customModuleProvider="target"> <tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" multipleSelection="NO" autosaveName="phpmon-sitelist-columns" rowHeight="54" headerView="xUg-Mq-OSh" viewBased="YES" id="cp3-34-pQj" customClass="PMTableView" customModule="PHP_Monitor" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="611" height="266"/> <rect key="frame" x="0.0" y="0.0" width="611" height="266"/>
@@ -1091,13 +1099,6 @@ Gw
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</tableHeaderView> </tableHeaderView>
</scrollView> </scrollView>
<progressIndicator maxValue="100" displayedWhenStopped="NO" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="ZiS-Gq-TLQ">
<rect key="frame" x="298" y="150" width="30" height="30"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="XK3-AR-Oc0"/>
<constraint firstAttribute="height" constant="30" id="lfW-dB-Eu3"/>
</constraints>
</progressIndicator>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="wcV-ed-8Bv"> <customView translatesAutoresizingMaskIntoConstraints="NO" id="wcV-ed-8Bv">
<rect key="frame" x="113" y="5" width="400" height="300"/> <rect key="frame" x="113" y="5" width="400" height="300"/>
<constraints> <constraints>

View File

@@ -24,4 +24,6 @@ protocol ValetListable {
func getListableUrl() -> URL? func getListableUrl() -> URL?
func getListableFavorited() -> Bool
} }

View File

@@ -13,6 +13,7 @@ class ValetProxy: ValetListable {
var tld: String var tld: String
var target: String var target: String
var secured: Bool = false var secured: Bool = false
var favorited: Bool = false
init(domain: String, target: String, secure: Bool, tld: String) { init(domain: String, target: String, secure: Bool, tld: String) {
self.domain = domain self.domain = domain
@@ -61,6 +62,10 @@ class ValetProxy: ValetListable {
return URL(string: "\(self.secured ? "https://" : "http://")\(self.domain).\(self.tld)") return URL(string: "\(self.secured ? "https://" : "http://")\(self.domain).\(self.tld)")
} }
func getListableFavorited() -> Bool {
return self.favorited
}
// MARK: - Interactions // MARK: - Interactions
func determineSecured() { func determineSecured() {

View File

@@ -61,6 +61,8 @@ class ValetSite: ValetListable {
?? "???" ?? "???"
} }
var favorited: Bool = false
init( init(
name: String, name: String,
tld: String, tld: String,
@@ -305,6 +307,10 @@ class ValetSite: ValetListable {
return URL(string: "\(self.secured ? "https://" : "http://")\(self.name).\(Valet.shared.config.tld)") return URL(string: "\(self.secured ? "https://" : "http://")\(self.name).\(Valet.shared.config.tld)")
} }
func getListableFavorited() -> Bool {
return self.favorited
}
// MARK: - Interactions // MARK: - Interactions
func toggleSecure() async throws { func toggleSecure() async throws {

View File

@@ -16,12 +16,14 @@ class DomainListNameCell: NSTableCellView, DomainListCellProtocol {
@IBOutlet weak var labelPathName: NSTextField! @IBOutlet weak var labelPathName: NSTextField!
func populateCell(with site: ValetSite) { func populateCell(with site: ValetSite) {
labelSiteName.stringValue = "\(site.name).\(site.tld)" let favoritePrefix = site.favorited ? "" : ""
labelSiteName.stringValue = "\(favoritePrefix)\(site.name).\(site.tld)"
labelPathName.stringValue = site.absolutePathRelative labelPathName.stringValue = site.absolutePathRelative
} }
func populateCell(with proxy: ValetProxy) { func populateCell(with proxy: ValetProxy) {
labelSiteName.stringValue = "\(proxy.domain).\(proxy.tld)" let favoritePrefix = proxy.favorited ? "" : ""
labelSiteName.stringValue = "\(favoritePrefix)\(proxy.domain).\(proxy.tld)"
labelPathName.stringValue = proxy.target labelPathName.stringValue = proxy.target
} }
} }

View File

@@ -67,6 +67,14 @@ extension DomainListVC {
// MARK: - Interactions with `valet` or terminal // MARK: - Interactions with `valet` or terminal
@objc func toggleFavorite() {
guard let selected = self.selected else {
return
}
Task { await toggleFavorite(domain: selected) }
}
@objc func toggleSecure() { @objc func toggleSecure() {
if selected is ValetSite { if selected is ValetSite {
Task { await toggleSecure(site: selected as! ValetSite) } Task { await toggleSecure(site: selected as! ValetSite) }
@@ -94,6 +102,22 @@ extension DomainListVC {
} }
} }
func toggleFavorite(domain: any ValetListable) async {
waitAndExecute {
do {
if let site = domain as? ValetSite {
site.favorited.toggle()
}
if let proxy = domain as? ValetProxy {
proxy.favorited.toggle()
}
// Reload the entire table as the sorting may be affected
self.reloadTable()
}
}
}
func toggleSecure(site: ValetSite) async { func toggleSecure(site: ValetSite) async {
waitAndExecute { waitAndExecute {
do { do {

View File

@@ -65,6 +65,7 @@ extension DomainListVC {
menu.addItem(HeaderView.asMenuItem(text: "domain_list.actions".localized)) menu.addItem(HeaderView.asMenuItem(text: "domain_list.actions".localized))
addToggleFavorite(to: menu, favorited: site.favorited)
addToggleSecure(to: menu, secured: site.secured) addToggleSecure(to: menu, secured: site.secured)
addUnlink(to: menu, with: site) addUnlink(to: menu, with: site)
@@ -172,6 +173,16 @@ extension DomainListVC {
) )
} }
private func addToggleFavorite(to menu: NSMenu, favorited: Bool) {
menu.addItem(
withTitle: favorited
? "domain_list.unfavorite".localized
: "domain_list.favorite".localized,
action: #selector(toggleFavorite),
keyEquivalent: ""
)
}
private func addMenuItemsForExtensions(to menu: NSMenu, for extensions: [PhpExtension], version: String) { private func addMenuItemsForExtensions(to menu: NSMenu, for extensions: [PhpExtension], version: String) {
var items: [NSMenuItem] = [ var items: [NSMenuItem] = [
NSMenuItem(title: "domain_list.applies_to".localized(version)) NSMenuItem(title: "domain_list.applies_to".localized(version))
@@ -200,6 +211,7 @@ extension DomainListVC {
let menu = NSMenu() let menu = NSMenu()
addOpenProxyInBrowser(to: menu) addOpenProxyInBrowser(to: menu)
addSeparator(to: menu) addSeparator(to: menu)
addToggleFavorite(to: menu, favorited: proxy.favorited)
addToggleSecure(to: menu, secured: proxy.secured) addToggleSecure(to: menu, secured: proxy.secured)
addRemoveProxy(to: menu) addRemoveProxy(to: menu)
return menu return menu

View File

@@ -221,7 +221,9 @@ class DomainListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource
default: break default: break
} }
self.domains = descriptor.ascending ? sorted.reversed() : sorted sorted = descriptor.ascending ? sorted.reversed() : sorted
self.domains = sorted.sorted { $0.getListableFavorited() && !$1.getListableFavorited() }
} }
func addedNewSite(name: String, secureAfterLinking: Bool) async { func addedNewSite(name: String, secureAfterLinking: Bool) async {

View File

@@ -330,6 +330,8 @@ You may be asked for your password during the uninstallation process if file per
"domain_list.always_use_php" = "Always use PHP %@"; "domain_list.always_use_php" = "Always use PHP %@";
"domain_list.isolation_unavailable" = "Isolation Not Supported (in Valet 2)"; "domain_list.isolation_unavailable" = "Isolation Not Supported (in Valet 2)";
"domain_list.favorite" = "Favorite Domain";
"domain_list.unfavorite" = "Unfavorite Domain";
"domain_list.actions" = "Actions"; "domain_list.actions" = "Actions";
"domain_list.unlink" = "Unlink Directory"; "domain_list.unlink" = "Unlink Directory";
"domain_list.secure" = "Secure Domain"; "domain_list.secure" = "Secure Domain";