From 2d73c57426dac830e5c5b8d1ae6099f4a10017b8 Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Sun, 9 Nov 2025 14:14:58 +0100 Subject: [PATCH] Add Liquid Glass effect to player controls bar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor controls bar background styling with platform-specific effects: - Add Liquid Glass effect for iOS 26+ using new glassEffect API - Fallback to ultraThinMaterial for iOS 15-25 - Fallback to blurred black overlay for iOS 14 and earlier - Extract background logic into reusable applyControlsBackground modifier - Adjust controls bar vertical offset for better alignment 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- Shared/Modifiers/PlayerOverlayModifier.swift | 2 +- Shared/Views/ControlsBar.swift | 59 ++++++++++++++++++-- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/Shared/Modifiers/PlayerOverlayModifier.swift b/Shared/Modifiers/PlayerOverlayModifier.swift index a64f0e4e..94fa903d 100644 --- a/Shared/Modifiers/PlayerOverlayModifier.swift +++ b/Shared/Modifiers/PlayerOverlayModifier.swift @@ -22,7 +22,7 @@ struct PlayerOverlayModifier: ViewModifier { @ViewBuilder var overlay: some View { Group { ControlsBar(fullScreen: .constant(false), expansionState: $expansionState, playerBar: true) - .offset(x: expansionState == .mini && !controlsWhenMinimized ? 10 : 0, y: 0) + .offset(x: expansionState == .mini && !controlsWhenMinimized ? 10 : 0, y: -3) .frame(maxWidth: maxWidth, alignment: .trailing) .onAppear { if playerButtonIsExpanded { diff --git a/Shared/Views/ControlsBar.swift b/Shared/Views/ControlsBar.swift index d67cb40c..13bb69af 100644 --- a/Shared/Views/ControlsBar.swift +++ b/Shared/Views/ControlsBar.swift @@ -49,18 +49,15 @@ struct ControlsBar: View { .frame(maxWidth: 120) } } - .buttonStyle(.plain) .labelStyle(.iconOnly) .padding(.horizontal, 10) .padding(.vertical, 2) .frame(maxHeight: barHeight) .padding(.trailing, expansionState == .mini && !controlsWhenMinimized ? 8 : 0) - .modifier(ControlBackgroundModifier(enabled: backgroundEnabled)) - .clipShape(RoundedRectangle(cornerRadius: expansionState == .full || !playerBar ? 0 : 6)) - .overlay( - RoundedRectangle(cornerRadius: expansionState == .full || !playerBar ? 0 : 6) - .stroke(Color("ControlsBorderColor"), lineWidth: 0.5) + .applyControlsBackground( + enabled: backgroundEnabled, + cornerRadius: expansionState == .full || !playerBar ? 0 : 6 ) #if os(iOS) .background( @@ -342,3 +339,53 @@ struct ControlsBar_Previews: PreviewProvider { .injectFixtureEnvironmentObjects() } } + +// MARK: - View Extension for Conditional Modifiers +extension View { + @ViewBuilder + func `if`(_ condition: Bool, transform: (Self) -> Transform) -> some View { + if condition { + transform(self) + } else { + self + } + } + + @ViewBuilder + func applyControlsBackground(enabled: Bool, cornerRadius: CGFloat) -> some View { + if enabled { + if #available(iOS 26.0, macOS 26.0, tvOS 26.0, *) { + // Use Liquid Glass on iOS 26+ + self.glassEffect( + .regular.interactive(), + in: .rect(cornerRadius: cornerRadius) + ) + } else if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) { + // Fallback to ultraThinMaterial for iOS 15+ + self + .background( + RoundedRectangle(cornerRadius: cornerRadius) + .fill(.ultraThinMaterial) + ) + .overlay( + RoundedRectangle(cornerRadius: cornerRadius) + .stroke(Color("ControlsBorderColor"), lineWidth: 0.5) + ) + } else { + // Fallback for iOS 14 and earlier + self + .background( + RoundedRectangle(cornerRadius: cornerRadius) + .fill(Color.black.opacity(0.3)) + .blur(radius: 10) + ) + .overlay( + RoundedRectangle(cornerRadius: cornerRadius) + .stroke(Color("ControlsBorderColor"), lineWidth: 0.5) + ) + } + } else { + self.background(Color.clear) + } + } +}