Surface the existing pin (keep-from-cull) and per-file delete actions as visible inline buttons on each offline cache row instead of context-menu-only: a star toggles protection from auto-cull (and restore-if-missing), a trash culls that file early. Aligns wording/icons to the star metaphor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
42 lines
No EOL
1.5 KiB
Swift
42 lines
No EOL
1.5 KiB
Swift
import Foundation
|
|
|
|
/// One connected display — mirrors `display_list` in the MCP display tools.
|
|
public struct DisplayInfo: Identifiable, Sendable, Equatable, Codable {
|
|
public var id: UInt32 { displayId }
|
|
public let displayId: UInt32
|
|
public let name: String
|
|
public let width: Int
|
|
public let height: Int
|
|
public let isPrimary: Bool
|
|
public let isBuiltIn: Bool
|
|
|
|
public init(displayId: UInt32, name: String, width: Int, height: Int,
|
|
isPrimary: Bool, isBuiltIn: Bool) {
|
|
self.displayId = displayId
|
|
self.name = name
|
|
self.width = width
|
|
self.height = height
|
|
self.isPrimary = isPrimary
|
|
self.isBuiltIn = isBuiltIn
|
|
}
|
|
|
|
public var shortLabel: String {
|
|
if isBuiltIn { return "Built-in Display" }
|
|
return name.isEmpty ? "External Display" : name
|
|
}
|
|
|
|
/// First non-built-in screen (typical HDMI TV / monitor).
|
|
public static func pickTV(from displays: [DisplayInfo]) -> DisplayInfo? {
|
|
displays.first { !$0.isBuiltIn }
|
|
}
|
|
|
|
/// Resolve the playback target: explicit preference when still connected, else
|
|
/// auto-pick the external TV when present, else the primary display.
|
|
public static func resolve(preference: UInt32?, from displays: [DisplayInfo]) -> DisplayInfo? {
|
|
guard !displays.isEmpty else { return nil }
|
|
if let pref = preference, let found = displays.first(where: { $0.displayId == pref }) {
|
|
return found
|
|
}
|
|
return pickTV(from: displays) ?? displays.first(where: \.isPrimary) ?? displays.first
|
|
}
|
|
} |