d1c96c3ac4
Clicking the persistent Refresh row (⌘R) gave no immediate feedback while the menu stayed open: the provider card kept showing "Updated …" and only changed after switching cards or reopening the menu, prompting repeat clicks. Add two in-place updates that work during NSMenu tracking without rebuilding the open menu (preserving the deferred parent-rebuild policy from #1001/#1196/ #1325): - Live card subtitle: a narrowly-scoped MenuCardRefreshMonitor wraps the @Observable UsageStore and is injected via the environment. The header subtitle reads shouldShowRefreshingMenuCardIndicator(for:) so SwiftUI re-renders the single-line subtitle in place to "Refreshing…" while a refresh is in flight, converging to the next rebuild's state. The gate requires error == nil, so the multi-line error layout is never swapped and row height stays fixed. - Refresh row spinner: PersistentMenuActionItemView swaps its arrow.clockwise icon for a spinner occupying the same fixed 18pt slot (icon faded, not hidden, to avoid stack collapse). Forced on at click for instant feedback and reverted via the store observation on completion/failure. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
40 lines
1.5 KiB
Swift
40 lines
1.5 KiB
Swift
import SwiftUI
|
|
|
|
extension EnvironmentValues {
|
|
@Entry var menuItemHighlighted: Bool = false
|
|
/// Optional live-refresh monitor injected into menu card views so the provider card
|
|
/// subtitle can reflect the in-flight "Refreshing…" state in place while the NSMenu
|
|
/// stays open, without rebuilding the menu during AppKit tracking.
|
|
@Entry var menuCardRefreshMonitor: MenuCardRefreshMonitor?
|
|
}
|
|
|
|
enum MenuHighlightStyle {
|
|
static let selectionText = Color(nsColor: .selectedMenuItemTextColor)
|
|
static let normalPrimaryText = Color(nsColor: .controlTextColor)
|
|
static let normalSecondaryText = Color(nsColor: .secondaryLabelColor)
|
|
|
|
static func primary(_ highlighted: Bool) -> Color {
|
|
highlighted ? self.selectionText : self.normalPrimaryText
|
|
}
|
|
|
|
static func secondary(_ highlighted: Bool) -> Color {
|
|
highlighted ? self.selectionText : self.normalSecondaryText
|
|
}
|
|
|
|
static func error(_ highlighted: Bool) -> Color {
|
|
highlighted ? self.selectionText : Color(nsColor: .systemRed)
|
|
}
|
|
|
|
static func progressTrack(_ highlighted: Bool) -> Color {
|
|
highlighted ? self.selectionText.opacity(0.22) : Color(nsColor: .tertiaryLabelColor).opacity(0.22)
|
|
}
|
|
|
|
static func progressTint(_ highlighted: Bool, fallback: Color) -> Color {
|
|
highlighted ? self.selectionText : fallback
|
|
}
|
|
|
|
static func selectionBackground(_ highlighted: Bool) -> Color {
|
|
highlighted ? Color(nsColor: .selectedContentBackgroundColor) : .clear
|
|
}
|
|
}
|