Add per-page element customization and panel settings polish

Phase 5 of the player panels redesign:
- Per-page element toggles now rendered and editable for every page:
  comments (author avatars), related (thumbnails), chapters (thumbnails),
  queue (previously played section), tracks (video/audio/subtitles/speed
  sections)
- Page bar labels toggle (icons-only bar shows the selected page's name)
- Layout mode schematic diagram in the details panel settings
- NEW badge machinery for future page types (versionAdded on PanelPageType)
- Typed per-page settings accessors on PanelPageConfiguration and VM update
  helpers for each page kind
- Unit tests for per-page settings round-trip and accessor fallbacks

The standalone quality selector sheet is unaffected: section gating defaults
to everything visible and only the embedded tracks page passes preset
settings through.
This commit is contained in:
Arkadiusz Fal
2026-09-22 09:37:10 +02:00
parent 052cb76702
commit c289e7576e
19 changed files with 618 additions and 68 deletions

View File

@@ -868,6 +868,63 @@ final class PlayerControlsSettingsViewModel {
}
}
/// Synchronously updates the comments page element toggles.
func updatePanelCommentsSettingsSync(_ mutation: (inout CommentsPageSettings) -> Void) {
updatePanelSettingsSync { settings in
var comments = settings.configuration(for: .comments)?.commentsSettings ?? CommentsPageSettings()
mutation(&comments)
settings.updateSettings(.comments(comments), for: .comments)
}
}
/// Synchronously updates the related page element toggles.
func updatePanelRelatedSettingsSync(_ mutation: (inout RelatedPageSettings) -> Void) {
updatePanelSettingsSync { settings in
var related = settings.configuration(for: .related)?.relatedSettings ?? RelatedPageSettings()
mutation(&related)
settings.updateSettings(.related(related), for: .related)
}
}
/// Synchronously updates the chapters page element toggles.
func updatePanelChaptersSettingsSync(_ mutation: (inout ChaptersPageSettings) -> Void) {
updatePanelSettingsSync { settings in
var chapters = settings.configuration(for: .chapters)?.chaptersSettings ?? ChaptersPageSettings()
mutation(&chapters)
settings.updateSettings(.chapters(chapters), for: .chapters)
}
}
/// Synchronously updates the queue page element toggles.
func updatePanelQueueSettingsSync(_ mutation: (inout QueuePageSettings) -> Void) {
updatePanelSettingsSync { settings in
var queue = settings.configuration(for: .queue)?.queueSettings ?? QueuePageSettings()
mutation(&queue)
settings.updateSettings(.queue(queue), for: .queue)
}
}
/// Synchronously updates the tracks page element toggles.
func updatePanelTracksSettingsSync(_ mutation: (inout TracksPageSettings) -> Void) {
updatePanelSettingsSync { settings in
var tracks = settings.configuration(for: .tracks)?.tracksSettings ?? TracksPageSettings()
mutation(&tracks)
settings.updateSettings(.tracks(tracks), for: .tracks)
}
}
/// Whether the page bar shows labels next to icons.
var panelShowPageBarLabels: Bool {
panelSettings.effectiveShowPageBarLabels
}
/// Synchronously updates the page bar labels setting.
func syncPanelShowPageBarLabels(_ showLabels: Bool) {
updatePanelSettingsSync { settings in
settings.showPageBarLabels = showLabels
}
}
/// 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.