feat: add favorites with match-quality-aware ranking

This commit is contained in:
2026-10-14 00:00:43 +02:00
parent f3be147423
commit 9f6aa1db39
6 changed files with 180 additions and 10 deletions
@@ -6,6 +6,7 @@ final class ApplicationActionsController: NSViewController, NSSearchFieldDelegat
private let search = ActionsSearchField()
private let entries = [
ActionEntry(title: "Open", symbol: "arrow.up.forward.app", color: SunsetPalette.text),
ActionEntry(title: "Favorite", symbol: "star", color: SunsetPalette.text),
ActionEntry(title: "Show in Finder", symbol: "finder", color: SunsetPalette.text),
ActionEntry(title: "Reset ranking", symbol: "arrow.counterclockwise", color: SunsetPalette.text),
ActionEntry(title: "Quit application", symbol: "stop.circle", color: SunsetPalette.text),
@@ -24,6 +25,8 @@ final class ApplicationActionsController: NSViewController, NSSearchFieldDelegat
private var transitionGeneration = 0
private var panel: ActionsPanelView { view as! ActionsPanelView }
var open: (() -> Void)?
var toggleFavorite: (() -> Void)?
var isFavorite = false
var showInFinder: (() -> Void)?
var resetRanking: (() -> Void)?
var quit: (() -> Void)?
@@ -126,6 +129,13 @@ final class ApplicationActionsController: NSViewController, NSSearchFieldDelegat
let pill = anchor.superview ?? anchor
_ = view
applicationLabel.stringValue = application.name
let favorite = entries[1]
let favoriteTitle = isFavorite ? "Remove Favorite" : "Favorite"
favorite.button.attributedTitle = NSAttributedString(string: favoriteTitle, attributes: [
.foregroundColor: SunsetPalette.text, .font: NSFont.systemFont(ofSize: LauncherRowView.textSize, weight: .medium)
])
favorite.button.setAccessibilityLabel(favoriteTitle)
favorite.icon.image = NSImage(systemSymbolName: isFavorite ? "star.fill" : "star", accessibilityDescription: nil)
search.stringValue = ""
controlTextDidChange(Notification(name: NSControl.textDidChangeNotification))
transitionGeneration += 1
@@ -242,10 +252,11 @@ final class ApplicationActionsController: NSViewController, NSSearchFieldDelegat
close()
switch index {
case 0: open?()
case 1: showInFinder?()
case 2: resetRanking?()
case 3: quit?()
case 4: uninstall?()
case 1: toggleFavorite?()
case 2: showInFinder?()
case 3: resetRanking?()
case 4: quit?()
case 5: uninstall?()
default: break
}
}
@@ -255,6 +266,7 @@ final class ApplicationActionsController: NSViewController, NSSearchFieldDelegat
private struct ActionEntry {
let view = LauncherRowView()
let button: NSButton
let icon = ActionIconView()
let returnKey = ShortcutIndicator("↵")
init(title: String, symbol: String, color: NSColor) {
@@ -267,7 +279,6 @@ private struct ActionEntry {
.foregroundColor: color, .font: NSFont.systemFont(ofSize: LauncherRowView.textSize, weight: .medium)
])
button.setAccessibilityLabel(title)
let icon = ActionIconView()
icon.image = NSImage(systemSymbolName: symbol, accessibilityDescription: nil)
?? (symbol == "finder" ? NSWorkspace.shared.icon(forFile: "/System/Library/CoreServices/Finder.app") : nil)
icon.contentTintColor = color
@@ -591,6 +591,12 @@ final class LauncherWindowController: NSWindowController, NSWindowDelegate, NSSe
(window as? LauncherPanel)?.resetNumberHints()
let application = results[tableView.selectedRow]
actions.open = { [weak self] in self?.openApplication(application) }
actions.isFavorite = history.isFavorite(application)
actions.toggleFavorite = { [weak self] in
guard let self else { return }
self.history.toggleFavorite(application)
self.updateResults(preservingSelection: true)
}
actions.showInFinder = { [weak self] in
self?.dismiss(restoringFocus: false)
NSWorkspace.shared.activateFileViewerSelecting([application.url])