diff --git a/Yattee/Services/Navigation/NavigationDestination.swift b/Yattee/Services/Navigation/NavigationDestination.swift index adc69dc7..8d0cfd42 100644 --- a/Yattee/Services/Navigation/NavigationDestination.swift +++ b/Yattee/Services/Navigation/NavigationDestination.swift @@ -184,13 +184,17 @@ private struct MediaSourceByIDView: View { struct NavigationDestinationHandlerModifier: ViewModifier { func body(content: Content) -> some View { content + .opaqueWindowBackground() .navigationDestination(for: NavigationDestination.self) { destination in - if let transitionID = destination.transitionID { - destination.view() - .zoomTransitionDestination(id: transitionID) - } else { - destination.view() + Group { + if let transitionID = destination.transitionID { + destination.view() + .zoomTransitionDestination(id: transitionID) + } else { + destination.view() + } } + .opaqueWindowBackground() } } } diff --git a/Yattee/Views/Components/OpaqueWindowBackground.swift b/Yattee/Views/Components/OpaqueWindowBackground.swift new file mode 100644 index 00000000..c2fe528e --- /dev/null +++ b/Yattee/Views/Components/OpaqueWindowBackground.swift @@ -0,0 +1,33 @@ +// +// OpaqueWindowBackground.swift +// Yattee +// +// Unified opaque background for main content views on macOS. +// + +import SwiftUI + +/// Applies an opaque window background on macOS. +/// +/// Without an explicit background, content sits on the translucent window +/// material, which picks up a wallpaper tint (often bluish in dark mode) and +/// clashes with views that draw `windowBackgroundColor` themselves (lists, +/// gradient fades). No-op on other platforms. +struct OpaqueWindowBackgroundModifier: ViewModifier { + func body(content: Content) -> some View { + #if os(macOS) + content + .background(Color(nsColor: .windowBackgroundColor).ignoresSafeArea()) + #else + content + #endif + } +} + +extension View { + /// Gives the view an opaque window background on macOS so all main content + /// views share the same background color. No-op on iOS/tvOS. + func opaqueWindowBackground() -> some View { + modifier(OpaqueWindowBackgroundModifier()) + } +} diff --git a/Yattee/Views/Video/VideoInfoView.swift b/Yattee/Views/Video/VideoInfoView.swift index 985bba6f..f1a63e80 100644 --- a/Yattee/Views/Video/VideoInfoView.swift +++ b/Yattee/Views/Video/VideoInfoView.swift @@ -259,6 +259,9 @@ struct VideoInfoView: View { videoContent } } + // Opaque background so the header gradient (which fades to windowBackgroundColor) + // blends seamlessly even when presented outside a navigation stack. + .opaqueWindowBackground() .task { await loadInitialVideoIfNeeded() }