From 71eb2aacc775d29b7d40f8dda2eea6a97cd07a07 Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Sat, 20 Jun 2026 22:49:22 +0200 Subject: [PATCH] Position macOS seek preview just above the progress bar The storyboard seek preview was anchored to the top of the control-bar pill and floated well above it. Anchor the preview and chapter capsule up from the pill bottom (via geometry height) so they overlap the button row and sit just above the progress bar, matching iOS proximity. --- .../Views/Player/macOS/MacOSControlBar.swift | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Yattee/Views/Player/macOS/MacOSControlBar.swift b/Yattee/Views/Player/macOS/MacOSControlBar.swift index 9dc664dd..2ea8bccd 100644 --- a/Yattee/Views/Player/macOS/MacOSControlBar.swift +++ b/Yattee/Views/Player/macOS/MacOSControlBar.swift @@ -82,35 +82,46 @@ struct MacOSControlBar: View { .frame(maxWidth: 500) .glassBackground(.regular, in: .rect(cornerRadius: 16), colorScheme: globalSettings.controlBarTheme.colorScheme) .shadow(color: .black.opacity(0.3), radius: 8, y: 4) - // Seek preview overlay - positioned above the control bar + // Seek preview overlay - positioned just above the progress bar (overlapping the bar) .overlay(alignment: .bottom) { if (isDragging || isHoveringProgress), !playerState.isLive { GeometryReader { geometry in let pos = seekPreviewPosition(geometry: geometry, previewWidth: playerState.preferredStoryboard != nil ? 176 : 80) + // Position previews just above the progress bar so they overlap the control + // bar (button row) rather than floating above the whole pill. Measured up from + // the pill bottom, so it stays correct regardless of button-row height. + // Bottom inset = pill bottom padding (10) + timeline row height (~20). + let progressBarTop = geometry.size.height - 30 + let previewGap: CGFloat = 6 + let capsuleDelta: CGFloat = 26 if let storyboard = playerState.preferredStoryboard { + let previewY = progressBarTop - 102 - previewGap // storyboard preview height ~102 + seekPreviewView(storyboard: storyboard) - .offset(x: pos.clampedX, y: -150) + .offset(x: pos.clampedX, y: previewY) if showChapters, let chapter = playerState.chapters.last(where: { $0.startTime <= pos.progress * playerState.duration }) { ChapterCapsuleView(title: chapter.title, buttonBackground: .none) .positioned(xTarget: pos.centerX, availableWidth: geometry.size.width) - .offset(y: -176) + .offset(y: previewY - capsuleDelta) } } else { + let previewY = progressBarTop - 32 - previewGap // time pill height ~32 + SeekTimePreviewView( seekTime: pos.progress * playerState.duration, buttonBackground: .none, theme: .dark ) - .offset(x: pos.clampedX, y: -60) + .offset(x: pos.clampedX, y: previewY) .transition(.opacity.combined(with: .scale(scale: 0.9))) .animation(.easeInOut(duration: 0.15), value: isDragging || isHoveringProgress) if showChapters, let chapter = playerState.chapters.last(where: { $0.startTime <= pos.progress * playerState.duration }) { ChapterCapsuleView(title: chapter.title, buttonBackground: .none) .positioned(xTarget: pos.centerX, availableWidth: geometry.size.width) - .offset(y: -86) + .offset(y: previewY - capsuleDelta) } } }