mirror of
https://github.com/yattee/yattee.git
synced 2026-10-25 14:12:53 +00:00
Add details panel preset settings UI and default visibility
Phase 2 of the player panels redesign: - New "Details Panel" screen in Player Controls settings: page reorder/enable list with per-page editor (info element toggles), and a default panel visibility picker (hidden/visible/remember). - PlayerControlsSettingsViewModel gains panelSettings bindings with the usual debounced-save flow; the last enabled page cannot be disabled. - Built-in presets bumped to v9 with explicit default panelSettings. - The preset's default visibility now drives the wide-layout panel on player open and on entering landscape, replacing the hard hidden resets; "remember" restores the new detailsPanelLastVisible setting recorded on user toggles. Applied once per expanded player session (flag on NavigationCoordinator survives re-mounts). - WideScreenPlayerLayout picks up external visibility writes so the async-loaded default reaches the mounted layout. - Unit tests for PanelSettings Codable compatibility (round-trip, old JSON, unknown page types/discriminators/enum values); removed stale PlayerInfoTab tests left from Phase 1.
This commit is contained in:
@@ -11,7 +11,7 @@ extension LayoutPreset {
|
||||
/// Bump this version whenever any built-in preset definition changes.
|
||||
/// On launch, the app compares this against the last-applied version
|
||||
/// and replaces stale built-in presets with fresh copies from code.
|
||||
static let builtInPresetsVersion = 8
|
||||
static let builtInPresetsVersion = 9
|
||||
|
||||
// MARK: - Built-in Preset IDs
|
||||
|
||||
@@ -131,7 +131,8 @@ extension LayoutPreset {
|
||||
progressBarSettings: ProgressBarSettings(),
|
||||
gesturesSettings: gesturesSettings,
|
||||
playerPillSettings: playerPillSettings,
|
||||
miniPlayerSettings: miniPlayerSettings
|
||||
miniPlayerSettings: miniPlayerSettings,
|
||||
panelSettings: .default
|
||||
)
|
||||
}
|
||||
|
||||
@@ -192,7 +193,8 @@ extension LayoutPreset {
|
||||
progressBarSettings: ProgressBarSettings(),
|
||||
gesturesSettings: nil,
|
||||
playerPillSettings: nil,
|
||||
miniPlayerSettings: MiniPlayerSettings()
|
||||
miniPlayerSettings: MiniPlayerSettings(),
|
||||
panelSettings: .default
|
||||
)
|
||||
}
|
||||
|
||||
@@ -285,7 +287,8 @@ extension LayoutPreset {
|
||||
progressBarSettings: progressBarSettings,
|
||||
gesturesSettings: gesturesSettings,
|
||||
playerPillSettings: playerPillSettings,
|
||||
miniPlayerSettings: miniPlayerSettings
|
||||
miniPlayerSettings: miniPlayerSettings,
|
||||
panelSettings: .default
|
||||
)
|
||||
}
|
||||
|
||||
@@ -336,7 +339,8 @@ extension LayoutPreset {
|
||||
progressBarSettings: progressBarSettings,
|
||||
gesturesSettings: nil,
|
||||
playerPillSettings: nil,
|
||||
miniPlayerSettings: MiniPlayerSettings()
|
||||
miniPlayerSettings: MiniPlayerSettings(),
|
||||
panelSettings: .default
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - Panel Page Type
|
||||
|
||||
@@ -77,10 +78,22 @@ enum PanelLayoutMode: String, Codable, Sendable {
|
||||
// MARK: - Default Visibility
|
||||
|
||||
/// Default panel visibility when the player opens on iPad/macOS.
|
||||
enum PanelDefaultVisibility: String, Codable, Sendable {
|
||||
enum PanelDefaultVisibility: String, Codable, CaseIterable, Sendable {
|
||||
case hidden
|
||||
case visible
|
||||
case remember
|
||||
|
||||
/// Localized name for the settings picker.
|
||||
var displayName: String {
|
||||
switch self {
|
||||
case .hidden:
|
||||
return String(localized: "panel.defaultVisibility.hidden")
|
||||
case .visible:
|
||||
return String(localized: "panel.defaultVisibility.visible")
|
||||
case .remember:
|
||||
return String(localized: "panel.defaultVisibility.remember")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Per-Page Settings
|
||||
@@ -288,6 +301,12 @@ struct PanelSettings: Codable, Hashable, Sendable {
|
||||
self.showPageBarLabels = showPageBarLabels
|
||||
}
|
||||
|
||||
/// In-memory cache of the active preset's panel settings, refreshed by the
|
||||
/// player whenever the layout loads. Lets synchronous appear paths (e.g.
|
||||
/// default-visibility resets) read the last known value before the async
|
||||
/// layout fetch completes.
|
||||
nonisolated(unsafe) static var cached: PanelSettings = .default
|
||||
|
||||
static let `default` = PanelSettings(pages: [
|
||||
PanelPageConfiguration(pageType: .info, region: .belowVideo),
|
||||
PanelPageConfiguration(pageType: .comments, region: .belowVideo),
|
||||
@@ -328,6 +347,36 @@ struct PanelSettings: Codable, Hashable, Sendable {
|
||||
enabledPages().contains { $0.pageType == pageType }
|
||||
}
|
||||
|
||||
/// The stored configuration for a page type, if present.
|
||||
func configuration(for pageType: PanelPageType) -> PanelPageConfiguration? {
|
||||
normalizedPages.first { $0.pageType == pageType }
|
||||
}
|
||||
|
||||
// MARK: - Mutations (settings UI)
|
||||
|
||||
/// Replaces the stored pages with the normalized list so mutations by
|
||||
/// index operate on the same list the UI displays.
|
||||
mutating func normalize() {
|
||||
pages = normalizedPages
|
||||
}
|
||||
|
||||
mutating func setEnabled(_ isEnabled: Bool, for pageType: PanelPageType) {
|
||||
normalize()
|
||||
guard let index = pages.firstIndex(where: { $0.pageType == pageType }) else { return }
|
||||
pages[index].isEnabled = isEnabled
|
||||
}
|
||||
|
||||
mutating func movePages(fromOffsets source: IndexSet, toOffset destination: Int) {
|
||||
normalize()
|
||||
pages.move(fromOffsets: source, toOffset: destination)
|
||||
}
|
||||
|
||||
mutating func updateSettings(_ newSettings: PanelPageSettings?, for pageType: PanelPageType) {
|
||||
normalize()
|
||||
guard let index = pages.firstIndex(where: { $0.pageType == pageType }) else { return }
|
||||
pages[index].settings = newSettings
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case pages
|
||||
case layoutMode
|
||||
|
||||
Reference in New Issue
Block a user