Files
yattee/Yattee/Core/Settings/SettingsKey.swift
Arkadiusz Fal c33d125553 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.
2026-09-21 23:25:10 +02:00

193 lines
6.2 KiB
Swift

//
// SettingsKey.swift
// Yattee
//
// Keys used for storing settings in UserDefaults and iCloud.
//
import Foundation
/// Keys for storing settings values.
/// Used internally by SettingsManager for persistence.
enum SettingsKey: String, CaseIterable {
// General
case theme
case accentColor
case customAccentColor
case accentColorDark
case customAccentColorDark
case useSeparateDarkAccentColor
case showWatchedCheckmark
// Accounts
case showAccountPickers
// Playback
case preferredQuality
case cellularQuality
case autoplay
case backgroundPlayback
case preferredAudioLanguage
case preferredSubtitlesLanguage
case resumeAction
case tvOSMenuButtonClosesVideo
case allowSoftwareDecodedFormats
case audioOnlyMode
// SponsorBlock
case sponsorBlockEnabled
case sponsorBlockCategories
case sponsorBlockAPIURL
// Return YouTube Dislike
case returnYouTubeDislikeEnabled
// DeArrow
case deArrowEnabled
case deArrowReplaceTitles
case deArrowReplaceThumbnails
case deArrowAPIURL
case deArrowThumbnailAPIURL
// Short link resolution
case resolveShortLinksEnabled
// Platform-specific
case macPlayerSeparateWindow
case macPlayerFloating
case macControlsBarOffsetX // Normalized X offset of macOS control bar from default position
case macControlsBarOffsetY // Normalized Y offset of macOS control bar from default position
case playerSheetAutoResize
case listStyle
// Feed
case feedCacheValidityMinutes
// Player
case keepPlayerPinned
case hapticFeedbackEnabled
case hapticFeedbackIntensity
case inAppOrientationLock
case rotateToMatchAspectRatio
case preferPortraitBrowsing
// Home
case homeShortcutOrder
case homeShortcutVisibility
case homeShortcutLayout
case homeShortcutCardStyle
case homeShortcutCardColor
case homeShortcutColorfulPalette
case homeShortcutCustomPaletteColors
case homeSectionOrder
case homeSectionVisibility
case homeSectionItemsLimit
case homeSectionLayout
// Top Shelf (tvOS)
case topShelfSections
// Tab Bar (compact size class)
case tabBarItemOrder
case tabBarItemVisibility
case tabBarStartupTab
// Sidebar
case sidebarMainItemOrder
case sidebarMainItemVisibility
case sidebarStartupTab
case sidebarSourcesEnabled
case sidebarSourceSort
case sidebarSourcesLimitEnabled
case sidebarMaxSources
case sidebarChannelsEnabled
case sidebarMaxChannels
case sidebarChannelSort
case sidebarChannelsLimitEnabled
case sidebarPlaylistsEnabled
case sidebarMaxPlaylists
case sidebarPlaylistSort
case sidebarPlaylistsLimitEnabled
// Remote Control
case remoteControlCustomDeviceName
case remoteControlHideWhenBackgrounded
// Advanced
case showAdvancedStreamDetails
case showPlayerAreaDebug
case showTVDebugButton
case verboseMPVLogging
case verboseRemoteControlLogging
case mpvBufferSeconds
case mpvUseEDLStreams
case zoomTransitionsEnabled
case tvMatchDisplayFrameRate
case tvMatchDisplayDynamicRange
case tvAudioDelayMs
case tvVideoSyncMode
// Details panel
case floatingDetailsPanelSide // Landscape only - which side the panel appears on
case floatingDetailsPanelWidth // Resizable panel width in wide layout
case landscapeDetailsPanelVisible
case landscapeDetailsPanelPinned
case detailsPanelLastVisible // Last user-set visibility, for the "remember" default
// Player Controls
case activeControlsPresetID
// Video Swipe Actions
case videoSwipeActionOrder
case videoSwipeActionVisibility
// Onboarding
case onboardingCompleted
/// Whether this key should have platform-specific prefixes.
/// Platform-specific keys are stored under a `iOS.` / `macOS.` / `tvOS.` prefix
/// in both UserDefaults and iCloud, so each platform family syncs independently.
var isPlatformSpecific: Bool {
switch self {
case .preferredQuality, .cellularQuality, .allowSoftwareDecodedFormats, .audioOnlyMode,
.macPlayerSeparateWindow, .macPlayerFloating, .listStyle,
.macControlsBarOffsetX, .macControlsBarOffsetY,
// Home layout — different UI paradigms per platform
.homeShortcutOrder, .homeShortcutVisibility, .homeShortcutLayout, .homeShortcutCardStyle,
.homeShortcutCardColor, .homeShortcutColorfulPalette, .homeShortcutCustomPaletteColors,
.homeSectionOrder, .homeSectionVisibility, .homeSectionItemsLimit, .homeSectionLayout,
// Top Shelf — tvOS only
.topShelfSections,
// Tab bar (compact size class) layout
.tabBarItemOrder, .tabBarItemVisibility, .tabBarStartupTab,
// Sidebar layout/selection
.sidebarMainItemOrder, .sidebarMainItemVisibility, .sidebarStartupTab,
.sidebarSourcesEnabled, .sidebarSourceSort, .sidebarSourcesLimitEnabled, .sidebarMaxSources,
.sidebarChannelsEnabled, .sidebarMaxChannels, .sidebarChannelSort, .sidebarChannelsLimitEnabled,
.sidebarPlaylistsEnabled, .sidebarMaxPlaylists, .sidebarPlaylistSort, .sidebarPlaylistsLimitEnabled,
// Player details panel — iOS/iPadOS only, different on other platforms
.floatingDetailsPanelSide, .floatingDetailsPanelWidth,
.landscapeDetailsPanelVisible, .landscapeDetailsPanelPinned,
.detailsPanelLastVisible,
// Video swipe actions — touch-gesture feature
.videoSwipeActionOrder, .videoSwipeActionVisibility:
return true
default:
return false
}
}
/// Whether this key should only be stored locally (not synced to iCloud).
/// Used for device-specific settings like custom device name for remote control.
var isLocalOnly: Bool {
switch self {
case .remoteControlCustomDeviceName, .remoteControlHideWhenBackgrounded,
.activeControlsPresetID, // Per-device preset selection
.onboardingCompleted: // Per-device onboarding state
return true
default:
return false
}
}
}