ios: Liquid Glass mini player, adjustable karaoke softness (1.0.7)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e98d595365
commit
d52a3e257f
6 files changed
+163
-56
No files matched your search
@@ -14,15 +14,12 @@ struct RootView: View {
|
||||
root(t).miniPlayerRoom()
|
||||
.navigationDestination(for: Route.self) { destination($0).miniPlayerRoom() }
|
||||
}
|
||||
// Floats over the screens; each screen leaves room for it so nothing ends up underneath.
|
||||
.overlay(alignment: .bottom) {
|
||||
if g.playback.current != nil { MiniPlayer().transition(.move(edge: .bottom).combined(with: .opacity)) }
|
||||
}
|
||||
.animation(.spring(duration: 0.35), value: g.playback.current != nil)
|
||||
.modifier(FloatingMiniPlayer())
|
||||
.tabItem { Label(t.rawValue, systemImage: t.icon) }
|
||||
.tag(t)
|
||||
}
|
||||
}
|
||||
.modifier(GlassMiniPlayerHost())
|
||||
.sheet(isPresented: Binding(get: { ui.nowPlayingOpen }, set: { ui.nowPlayingOpen = $0 })) {
|
||||
NowPlayingScreen()
|
||||
.overlayHost(ui.overlays, level: 1)
|
||||
@@ -72,11 +69,43 @@ struct RootView: View {
|
||||
}
|
||||
}
|
||||
|
||||
/// iOS 26.1 and up put the mini player in the tab bar's glass accessory; older ones float a card over each tab.
|
||||
private let glassAccessory: Bool = { if #available(iOS 26.1, *) { return true } else { return false } }()
|
||||
|
||||
private struct GlassMiniPlayerHost: ViewModifier {
|
||||
private var g: AppGraph { .shared }
|
||||
func body(content: Content) -> some View {
|
||||
if #available(iOS 26.1, *) {
|
||||
content
|
||||
.tabViewBottomAccessory(isEnabled: g.playback.current != nil) { MiniPlayer() }
|
||||
.tabBarMinimizeBehavior(.onScrollDown)
|
||||
} else {
|
||||
content
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Floats over the screens; each screen leaves room for it so nothing ends up underneath.
|
||||
private struct FloatingMiniPlayer: ViewModifier {
|
||||
private var g: AppGraph { .shared }
|
||||
func body(content: Content) -> some View {
|
||||
if glassAccessory {
|
||||
content
|
||||
} else {
|
||||
content
|
||||
.overlay(alignment: .bottom) {
|
||||
if g.playback.current != nil { MiniPlayer().transition(.move(edge: .bottom).combined(with: .opacity)) }
|
||||
}
|
||||
.animation(.spring(duration: 0.35), value: g.playback.current != nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct MiniPlayerRoom: ViewModifier {
|
||||
private var g: AppGraph { .shared }
|
||||
func body(content: Content) -> some View {
|
||||
content.safeAreaInset(edge: .bottom, spacing: 0) {
|
||||
if g.playback.current != nil { Color.clear.frame(height: 66) }
|
||||
if !glassAccessory && g.playback.current != nil { Color.clear.frame(height: 66) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user