Sync sidebar/tab bar/home layout per-platform via iCloud

Extends `SettingsKey.isPlatformSpecific` to cover home, tab bar, and
sidebar layout, plus player details panel and video swipe actions, so
iOS devices sync these with other iOS devices (and tvOS with tvOS,
macOS with macOS) instead of overwriting each other via the shared
iCloud key. Adds a one-shot migration that copies legacy unprefixed
values into the new platform-prefixed slots locally and in iCloud,
preserving protected-key timestamps.
This commit is contained in:
Arkadiusz Fal
2026-04-14 01:16:52 +02:00
parent f4605e7390
commit 9e95a91284
3 changed files with 98 additions and 1 deletions

View File

@@ -116,9 +116,26 @@ enum SettingsKey: String, CaseIterable {
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, .macPlayerMode, .listStyle:
case .preferredQuality, .cellularQuality, .macPlayerMode, .listStyle,
// Home layout different UI paradigms per platform
.homeShortcutOrder, .homeShortcutVisibility, .homeShortcutLayout,
.homeSectionOrder, .homeSectionVisibility, .homeSectionItemsLimit,
// 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,
// Video swipe actions touch-gesture feature
.videoSwipeActionOrder, .videoSwipeActionVisibility:
return true
default:
return false