Files
yattee/Yattee/Models/VideoListLayout.swift
Arkadiusz Fal 4770bbe3b9 Remove dead code found by Periphery on all platforms
Delete declarations that Periphery reports unused on every platform that
compiles them (iOS, macOS, tvOS), including nine views used only by their
own previews. Platform-gated code still used on another platform, device-
only MPV render paths, migration models, CloudKit record names, App
Intents metadata and unused parameters are kept.
2026-10-08 23:57:56 +02:00

137 lines
4.1 KiB
Swift

//
// VideoListLayout.swift
// Yattee
//
// Layout options for video listing views.
//
import SwiftUI
/// Layout type for video lists.
enum VideoListLayout: String, CaseIterable {
case list
case grid
var displayName: LocalizedStringKey {
switch self {
case .list: "viewOptions.layout.list"
case .grid: "viewOptions.layout.grid"
}
}
var systemImage: String {
switch self {
case .list: "list.bullet"
case .grid: "square.grid.2x2"
}
}
}
// MARK: - Grid Layout Helpers
/// Constants for grid layout calculations.
enum GridConstants {
/// Minimum width for a video card thumbnail to remain usable.
static let minCardWidth: CGFloat = {
#if os(tvOS)
200
#else
100
#endif
}()
/// Spacing between grid items.
static let spacing: CGFloat = {
#if os(tvOS)
48
#else
12
#endif
}()
/// Horizontal padding for the grid container.
static let horizontalPadding: CGFloat = 32
/// Maximum allowed columns (to prevent excessive density).
static let maxAllowedColumns = 6
/// Minimum allowed columns. tvOS doesn't make sense with a single column.
static let minAllowedColumns: Int = {
#if os(tvOS)
2
#else
1
#endif
}()
/// Threshold for compact card styling (columns >= this use compact mode).
static let compactThreshold = 3
}
/// Calculates the maximum number of grid columns that fit within a given width.
/// - Parameters:
/// - width: Available container width
/// - minCardWidth: Minimum width per card (defaults to GridConstants.minCardWidth)
/// - spacing: Spacing between cards (defaults to GridConstants.spacing)
/// - Returns: Maximum columns that fit, clamped between 1 and maxAllowedColumns
func maxGridColumns(
forWidth width: CGFloat,
minCardWidth: CGFloat = GridConstants.minCardWidth,
spacing: CGFloat = GridConstants.spacing
) -> Int {
let availableWidth = width - GridConstants.horizontalPadding
// Formula: availableWidth = (columns * minCardWidth) + ((columns - 1) * spacing)
// Solving for columns: columns = (availableWidth + spacing) / (minCardWidth + spacing)
let maxColumns = Int((availableWidth + spacing) / (minCardWidth + spacing))
return max(GridConstants.minAllowedColumns, min(maxColumns, GridConstants.maxAllowedColumns))
}
/// Creates grid columns for a LazyVGrid with the specified count.
/// - Parameter count: Number of columns
/// - Returns: Array of flexible GridItems with top alignment
func makeGridColumns(count: Int) -> [GridItem] {
Array(repeating: GridItem(.flexible(), spacing: GridConstants.spacing, alignment: .top), count: max(GridConstants.minAllowedColumns, count))
}
// MARK: - Grid Layout Configuration
/// Encapsulates grid layout calculations for views with grid/list layouts.
///
/// Use this to eliminate repeated computed properties across grid-enabled views.
/// Create an instance with the current view width and user-selected column count,
/// then use the computed properties for layout decisions.
///
/// Usage:
/// ```swift
/// @State private var viewWidth: CGFloat = 0
/// @AppStorage("myView.gridColumns") private var gridColumns = 2
///
/// private var gridConfig: GridLayoutConfiguration {
/// GridLayoutConfiguration(viewWidth: viewWidth, gridColumns: gridColumns)
/// }
///
/// // Then use:
/// // gridConfig.effectiveColumns - actual column count
/// // gridConfig.isCompactCards - whether to use compact card styling
/// // gridConfig.maxColumns - for ViewOptionsSheet
/// ```
struct GridLayoutConfiguration {
let viewWidth: CGFloat
let gridColumns: Int
/// Maximum columns that fit in the current width.
var maxColumns: Int {
maxGridColumns(forWidth: viewWidth)
}
/// Effective column count, clamped to valid range.
var effectiveColumns: Int {
min(max(GridConstants.minAllowedColumns, gridColumns), max(GridConstants.minAllowedColumns, maxColumns))
}
/// Whether cards should use compact styling (3+ columns).
var isCompactCards: Bool {
effectiveColumns >= GridConstants.compactThreshold
}
}