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.
This commit is contained in:
Arkadiusz Fal
2026-10-09 23:59:41 +02:00
parent 6561c664e9
commit cf8d477351
2 changed files with 30 additions and 5 deletions

View File

@@ -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))

View File

@@ -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") {