mirror of
https://github.com/yattee/yattee.git
synced 2026-10-23 21:22: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:
@@ -790,6 +790,84 @@ final class PlayerControlsSettingsViewModel {
|
||||
queueDebouncedSave(preset: preset)
|
||||
}
|
||||
|
||||
// MARK: - Details Panel Settings
|
||||
|
||||
/// Current details panel settings from active preset, or default.
|
||||
var panelSettings: PanelSettings {
|
||||
activePreset?.layout.effectivePanelSettings ?? .default
|
||||
}
|
||||
|
||||
/// Ordered pages list for the settings UI (includes disabled pages).
|
||||
var panelPages: [PanelPageConfiguration] {
|
||||
panelSettings.normalizedPages
|
||||
}
|
||||
|
||||
/// Number of enabled panel pages.
|
||||
var enabledPanelPageCount: Int {
|
||||
panelSettings.enabledPages().count
|
||||
}
|
||||
|
||||
/// Current default panel visibility.
|
||||
var panelDefaultVisibility: PanelDefaultVisibility {
|
||||
panelSettings.effectiveDefaultVisibility
|
||||
}
|
||||
|
||||
/// Synchronously updates the default panel visibility.
|
||||
func syncPanelDefaultVisibility(_ visibility: PanelDefaultVisibility) {
|
||||
updatePanelSettingsSync { settings in
|
||||
settings.defaultVisibility = visibility
|
||||
}
|
||||
}
|
||||
|
||||
/// Enables or disables a panel page. The last enabled page cannot be
|
||||
/// disabled — the panel always needs at least one page.
|
||||
func setPanelPageEnabled(_ pageType: PanelPageType, isEnabled: Bool) {
|
||||
if !isEnabled {
|
||||
let enabled = panelSettings.enabledPages()
|
||||
if enabled.count <= 1, enabled.first?.pageType == pageType {
|
||||
return
|
||||
}
|
||||
}
|
||||
updatePanelSettingsSync { settings in
|
||||
settings.setEnabled(isEnabled, for: pageType)
|
||||
}
|
||||
}
|
||||
|
||||
/// Moves pages within the panel page order.
|
||||
func movePanelPages(fromOffsets source: IndexSet, toOffset destination: Int) {
|
||||
updatePanelSettingsSync { settings in
|
||||
settings.movePages(fromOffsets: source, toOffset: destination)
|
||||
}
|
||||
}
|
||||
|
||||
/// Synchronously updates the info page element toggles.
|
||||
func updatePanelInfoSettingsSync(_ mutation: (inout InfoPageSettings) -> Void) {
|
||||
updatePanelSettingsSync { settings in
|
||||
var info = settings.configuration(for: .info)?.infoSettings ?? InfoPageSettings()
|
||||
mutation(&info)
|
||||
settings.updateSettings(.info(info), for: .info)
|
||||
}
|
||||
}
|
||||
|
||||
/// Synchronously updates details panel settings with immediate UI feedback.
|
||||
/// Saves are debounced to avoid rapid disk writes.
|
||||
/// - Parameter mutation: A closure that mutates the panel settings.
|
||||
func updatePanelSettingsSync(_ mutation: (inout PanelSettings) -> Void) {
|
||||
guard var preset = activePreset, !preset.isBuiltIn else {
|
||||
error = "Cannot edit built-in presets. Duplicate it first."
|
||||
return
|
||||
}
|
||||
|
||||
var layout = preset.layout
|
||||
var settings = layout.effectivePanelSettings
|
||||
mutation(&settings)
|
||||
layout.panelSettings = settings
|
||||
preset = preset.withUpdatedLayout(layout)
|
||||
self.activePreset = preset
|
||||
|
||||
queueDebouncedSave(preset: preset)
|
||||
}
|
||||
|
||||
// MARK: - System Controls & Volume
|
||||
|
||||
/// Current system controls mode from active preset, or default.
|
||||
|
||||
Reference in New Issue
Block a user