Update from NavidromePlayer.zip (2026-04-03 20:04)
This commit is contained in:
parent
2fb1f6c19a
commit
36331d1f51
1 changed files with 47 additions and 43 deletions
|
|
@ -656,7 +656,11 @@ struct DynamicIslandView: View {
|
|||
private let accentPink = Color(red: 1.0, green: 0.176, blue: 0.333)
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
VStack(spacing: 0) {
|
||||
// Generous drag zone above and around the pill
|
||||
Color.clear
|
||||
.frame(height: 20)
|
||||
|
||||
HStack(spacing: 0) {
|
||||
// Leading: compact album art pill
|
||||
Group {
|
||||
|
|
@ -666,79 +670,79 @@ struct DynamicIslandView: View {
|
|||
Color.gray.opacity(0.3)
|
||||
}
|
||||
}
|
||||
.frame(width: 28, height: 28)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
|
||||
.frame(width: 32, height: 32)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
|
||||
.matchedGeometryEffect(id: "albumArt", in: namespace)
|
||||
.padding(.leading, 8)
|
||||
.padding(.leading, 10)
|
||||
|
||||
// Song info (compact)
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text(audioPlayer.currentSong?.title ?? "")
|
||||
.font(.system(size: 11, weight: .semibold))
|
||||
.font(.system(size: 12, weight: .semibold))
|
||||
.foregroundColor(.white)
|
||||
.lineLimit(1)
|
||||
Text(audioPlayer.currentSong?.artist ?? "")
|
||||
.font(.system(size: 9))
|
||||
.font(.system(size: 10))
|
||||
.foregroundColor(.white.opacity(0.5))
|
||||
.lineLimit(1)
|
||||
}
|
||||
.padding(.leading, 6)
|
||||
.frame(maxWidth: 100, alignment: .leading)
|
||||
.padding(.leading, 8)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
||||
// Center spacer (hardware cutout zone)
|
||||
Spacer()
|
||||
|
||||
// Trailing: compact visualizer
|
||||
// Trailing: compact visualizer or play button
|
||||
if VisualizerSettings.shared.enabled {
|
||||
CompactVisualizerView(
|
||||
isPlaying: audioPlayer.isPlaying,
|
||||
accentColor: colorExtractor.isLoaded ? colorExtractor.primaryColor : accentPink,
|
||||
height: 28
|
||||
height: 32
|
||||
)
|
||||
.frame(width: 60, height: 28)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 8))
|
||||
.frame(width: 64, height: 32)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 10))
|
||||
} else {
|
||||
// Play/pause when no visualizer
|
||||
Button(action: { audioPlayer.togglePlayPause() }) {
|
||||
Image(systemName: audioPlayer.isPlaying ? "pause.fill" : "play.fill")
|
||||
.font(.system(size: 14))
|
||||
.font(.system(size: 16))
|
||||
.foregroundColor(.white)
|
||||
}
|
||||
.frame(width: 36, height: 28)
|
||||
.frame(width: 40, height: 32)
|
||||
}
|
||||
|
||||
Spacer().frame(width: 8)
|
||||
Spacer().frame(width: 10)
|
||||
}
|
||||
.frame(height: 40)
|
||||
.frame(height: 48)
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 22, style: .continuous)
|
||||
RoundedRectangle(cornerRadius: 26, style: .continuous)
|
||||
.fill(.black)
|
||||
.shadow(color: .black.opacity(0.5), radius: 10, y: 2)
|
||||
)
|
||||
.padding(.horizontal, 40)
|
||||
.padding(.top, 10)
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
withAnimation(.easeInOut(duration: 0.35)) {
|
||||
showNowPlaying = true
|
||||
isDynamicIsland = false
|
||||
}
|
||||
}
|
||||
.gesture(
|
||||
DragGesture(minimumDistance: 10)
|
||||
.onEnded { value in
|
||||
if value.translation.height > 40 {
|
||||
// Drag down — return to mini player
|
||||
withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) {
|
||||
isDynamicIsland = false
|
||||
}
|
||||
}
|
||||
}
|
||||
.shadow(color: .black.opacity(0.6), radius: 12, y: 2)
|
||||
)
|
||||
.padding(.horizontal, 32)
|
||||
|
||||
// Extra drag zone below the pill
|
||||
Color.clear
|
||||
.frame(height: 30)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.ignoresSafeArea(edges: .top)
|
||||
.statusBarHidden(true)
|
||||
// Large hit area for the whole top region
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
withAnimation(.easeInOut(duration: 0.35)) {
|
||||
showNowPlaying = true
|
||||
isDynamicIsland = false
|
||||
}
|
||||
}
|
||||
.gesture(
|
||||
DragGesture(minimumDistance: 8)
|
||||
.onEnded { value in
|
||||
if value.translation.height > 25 {
|
||||
// Drag down — return to mini player
|
||||
withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) {
|
||||
isDynamicIsland = false
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue