From cf8d477351c1c677cf21b8e1c61d47d5fb4388bc Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Fri, 9 Oct 2026 23:59:41 +0200 Subject: [PATCH] Inset the mini player into the split view's detail column The floating overlay ignored the safe area, so the subscriptions channel strip sat under it on the iPhone Duo inner screen and iPad. --- Yattee/ContentView.swift | 10 ++++---- Yattee/Views/Navigation/UnifiedTabView.swift | 25 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/Yattee/ContentView.swift b/Yattee/ContentView.swift index 9f410999..9b060f41 100644 --- a/Yattee/ContentView.swift +++ b/Yattee/ContentView.swift @@ -206,8 +206,9 @@ struct AdaptiveTabView: View { } // The tab bar layout on iOS 26.1+ shows the mini player as the tab - // bar's bottom accessory; the split-view sidebar layout has no tab bar. - if usesSidebar || !Self.usesTabBottomAccessory { + // bar's bottom accessory; the split-view sidebar layout insets it + // into its detail column. + if !usesSidebar && !Self.usesTabBottomAccessory { miniPlayerOverlay } @@ -262,9 +263,8 @@ struct AdaptiveTabView: View { MiniPlayerView() } .padding(.horizontal, 16) - // The tab bar layout has a bottom tab bar (49pt) to clear; the sidebar - // layout (sidebarAdaptable) keeps its tabs at the top, so only float above the edge. - .padding(.bottom, usesSidebar ? 12 : 49 + 8) + // Clear the bottom tab bar (49pt) + .padding(.bottom, 49 + 8) // Use move-only transition (no opacity) to prevent thumbnail flash during collapse // The opacity transition caused video to appear faded during player sheet dismiss .transition(.move(edge: .bottom)) diff --git a/Yattee/Views/Navigation/UnifiedTabView.swift b/Yattee/Views/Navigation/UnifiedTabView.swift index b407447b..94ee9a68 100644 --- a/Yattee/Views/Navigation/UnifiedTabView.swift +++ b/Yattee/Views/Navigation/UnifiedTabView.swift @@ -87,6 +87,9 @@ struct UnifiedTabView: View { sidebar } detail: { detailForSelection + #if os(iOS) + .safeAreaInset(edge: .bottom, spacing: 0) { miniPlayerInset } + #endif } .zoomTransitionNamespace(zoomTransition) #if os(iOS) @@ -270,6 +273,28 @@ struct UnifiedTabView: View { } private var settingsManager: SettingsManager? { appEnvironment?.settingsManager } + + #if os(iOS) + /// The split view has no tab bar to host the mini player as a bottom + /// accessory, so it takes the detail column's bottom safe area instead: + /// floating content such as the subscriptions channel strip and the last + /// rows of every list then clear it, as they clear the tab accessory. + private var miniPlayerInset: some View { + let hasActiveVideo = appEnvironment?.playerService.state.currentVideo != nil + let isExpanded = appEnvironment?.navigationCoordinator.isPlayerExpanded ?? false + + return VStack(spacing: 0) { + if hasActiveVideo && !isExpanded { + MiniPlayerView() + .padding(.horizontal, 16) + .padding(.bottom, 12) + // Move-only transition (no opacity) prevents a thumbnail flash during collapse + .transition(.move(edge: .bottom)) + } + } + .animation(.spring(response: 0.3), value: hasActiveVideo) + } + #endif } #Preview("Unified Tab View") {