Files
yattee/Yattee/Models/PlayerControls/LayoutPreset.swift
2026-02-08 18:33:56 +01:00

111 lines
3.2 KiB
Swift

//
// LayoutPreset.swift
// Yattee
//
// A named preset containing a complete player controls layout.
//
import Foundation
/// A named preset containing a complete player controls layout.
struct LayoutPreset: Identifiable, Codable, Hashable, Sendable {
/// Unique identifier for this preset.
let id: UUID
/// User-visible name for the preset. Maximum 30 characters.
var name: String
/// When this preset was created.
let createdAt: Date
/// When this preset was last modified.
var updatedAt: Date
/// Whether this is a built-in preset (read-only).
let isBuiltIn: Bool
/// The device class this preset is for.
let deviceClass: DeviceClass
/// The complete player controls layout.
var layout: PlayerControlsLayout
// MARK: - Constants
/// Maximum length for preset names.
static let maxNameLength = 30
// MARK: - Initialization
/// Creates a new layout preset.
/// - Parameters:
/// - id: Unique identifier. Defaults to a new UUID.
/// - name: Preset name. Truncated to 30 characters.
/// - createdAt: Creation date. Defaults to now.
/// - updatedAt: Last modified date. Defaults to now.
/// - isBuiltIn: Whether this is a built-in preset.
/// - deviceClass: Device class for this preset. Defaults to current.
/// - layout: The player controls layout.
init(
id: UUID = UUID(),
name: String,
createdAt: Date = Date(),
updatedAt: Date = Date(),
isBuiltIn: Bool = false,
deviceClass: DeviceClass = .current,
layout: PlayerControlsLayout
) {
self.id = id
self.name = String(name.prefix(Self.maxNameLength))
self.createdAt = createdAt
self.updatedAt = updatedAt
self.isBuiltIn = isBuiltIn
self.deviceClass = deviceClass
self.layout = layout
}
// MARK: - Mutation
/// Creates a copy of this preset with updated layout and timestamp.
/// - Parameter layout: The new layout.
/// - Returns: A new preset with the updated layout.
func withUpdatedLayout(_ layout: PlayerControlsLayout) -> LayoutPreset {
var updated = self
updated.layout = layout
updated.updatedAt = Date()
return updated
}
/// Creates a copy of this preset with a new name.
/// - Parameter name: The new name.
/// - Returns: A new preset with the updated name.
func renamed(to name: String) -> LayoutPreset {
var updated = self
updated.name = String(name.prefix(Self.maxNameLength))
updated.updatedAt = Date()
return updated
}
/// Creates a duplicate of this preset as a custom (non-built-in) preset.
/// - Parameter name: Name for the duplicate.
/// - Returns: A new custom preset with the same layout.
func duplicate(name: String) -> LayoutPreset {
LayoutPreset(
name: name,
isBuiltIn: false,
deviceClass: deviceClass,
layout: layout
)
}
}
// MARK: - Equatable
extension LayoutPreset: Equatable {
static func == (lhs: LayoutPreset, rhs: LayoutPreset) -> Bool {
lhs.id == rhs.id &&
lhs.name == rhs.name &&
lhs.updatedAt == rhs.updatedAt
}
}