From 36331d1f51d6f6a6e6fce4fc0c6f28cca89f768b Mon Sep 17 00:00:00 2001 From: Dallas Groot Date: Fri, 3 Apr 2026 20:04:32 -0700 Subject: [PATCH] Update from NavidromePlayer.zip (2026-04-03 20:04) --- iOS/Views/Common/MainTabView.swift | 90 ++++++++++++++++-------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/iOS/Views/Common/MainTabView.swift b/iOS/Views/Common/MainTabView.swift index 4e39df8..494ef1e 100644 --- a/iOS/Views/Common/MainTabView.swift +++ b/iOS/Views/Common/MainTabView.swift @@ -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 + } + } + } + ) } }