mirror of
https://github.com/yattee/yattee.git
synced 2026-02-19 09:19:46 +00:00
Fix player dismiss gesture stuck after panel dismiss with comments expanded
Reset isCommentsExpanded and commentsFrame on the NavigationCoordinator directly when the portrait panel is dismissed, since PortraitDetailsPanel owns its own @State that doesn't sync back through .onChange during dismiss. Also track comments overlay frame via GeometryReader so the dismiss gesture can allow swipes outside the comments area instead of blanket-blocking.
This commit is contained in:
@@ -120,6 +120,9 @@ final class NavigationCoordinator {
|
||||
/// Progress bar frame in screen coordinates (for gesture conflict resolution).
|
||||
var progressBarFrame: CGRect = .zero
|
||||
|
||||
/// Comments overlay frame in screen coordinates (for gesture conflict resolution).
|
||||
var commentsFrame: CGRect = .zero
|
||||
|
||||
/// Current panscan value from UIKit pinch gesture (0.0 = fit, 1.0 = fill).
|
||||
/// Updated by ExpandedPlayerWindow's pinch gesture handler.
|
||||
var pinchPanscan: Double = 0.0
|
||||
|
||||
@@ -481,6 +481,9 @@ extension ExpandedPlayerSheet {
|
||||
withTransaction(transaction) {
|
||||
isPortraitPanelVisible = false
|
||||
navigationCoordinator?.isPortraitPanelVisible = false
|
||||
isCommentsExpanded = false
|
||||
navigationCoordinator?.isCommentsExpanded = false
|
||||
navigationCoordinator?.commentsFrame = .zero
|
||||
panelDragOffset = 0
|
||||
videoYOffset = 0 // Reset offset (centerY is now the base)
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ extension ExpandedPlayerSheet {
|
||||
|
||||
/// Collapses the comments overlay.
|
||||
func collapseComments() {
|
||||
navigationCoordinator?.commentsFrame = .zero
|
||||
// Use same animation as player sheet dismiss (0.3s, no bounce)
|
||||
withAnimation(.smooth(duration: 0.3)) {
|
||||
isCommentsExpanded = false
|
||||
|
||||
@@ -269,6 +269,23 @@ struct ExpandedPlayerSheet: View {
|
||||
}
|
||||
.opacity(isVisible ? 1 : 0)
|
||||
.allowsHitTesting(isVisible)
|
||||
.background(
|
||||
GeometryReader { commentsGeometry in
|
||||
Color.clear
|
||||
.onChange(of: commentsGeometry.frame(in: .global)) { _, newFrame in
|
||||
if isCommentsExpanded {
|
||||
navigationCoordinator?.commentsFrame = newFrame
|
||||
}
|
||||
}
|
||||
.onChange(of: isCommentsExpanded) { _, expanded in
|
||||
if expanded {
|
||||
navigationCoordinator?.commentsFrame = commentsGeometry.frame(in: .global)
|
||||
} else {
|
||||
navigationCoordinator?.commentsFrame = .zero
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
.ignoresSafeArea(edges: .bottom)
|
||||
}
|
||||
@@ -770,6 +787,7 @@ private struct PlayerEventHandlersModifier: ViewModifier {
|
||||
playerState?.commentsState = .idle
|
||||
playerState?.commentsContinuation = nil
|
||||
isCommentsExpanded = false
|
||||
navigationCoordinator?.commentsFrame = .zero
|
||||
isPanelExpanded = false
|
||||
panelExpandOffset = 0
|
||||
}
|
||||
|
||||
@@ -150,6 +150,8 @@ private final class DragToDismissGestureHandler: NSObject, UIGestureRecognizerDe
|
||||
var getProgressBarFrame: (() -> CGRect)?
|
||||
/// Returns true if a seek gesture is currently active (blocks pinch gesture)
|
||||
var isSeekGestureActive: (() -> Bool)?
|
||||
/// Returns the comments overlay frame in screen coordinates (for gesture conflict resolution)
|
||||
var getCommentsFrame: (() -> CGRect)?
|
||||
|
||||
// Main window scaling callbacks (Apple Music-style effect)
|
||||
var onMainWindowScaleChanged: ((CGFloat) -> Void)?
|
||||
@@ -341,10 +343,18 @@ private final class DragToDismissGestureHandler: NSObject, UIGestureRecognizerDe
|
||||
return false
|
||||
}
|
||||
|
||||
// Don't begin dismiss gesture when comments are expanded (they handle their own dismiss)
|
||||
// When comments are expanded, only block dismiss if touch is within comments frame
|
||||
if isCommentsExpanded?() == true {
|
||||
let commentsFrame = getCommentsFrame?() ?? .zero
|
||||
if !commentsFrame.isEmpty {
|
||||
let touchLocation = panGesture.location(in: nil)
|
||||
if commentsFrame.contains(touchLocation) {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false // No frame info — fall back to blanket blocking
|
||||
}
|
||||
}
|
||||
|
||||
// Don't begin dismiss gesture when adjusting volume/brightness sliders
|
||||
if isAdjustingPlayerSliders?() == true {
|
||||
@@ -840,6 +850,9 @@ final class ExpandedPlayerWindowManager {
|
||||
handler.isSeekGestureActive = { [weak self] in
|
||||
self?.appEnvironment?.navigationCoordinator.isSeekGestureActive ?? false
|
||||
}
|
||||
handler.getCommentsFrame = { [weak self] in
|
||||
self?.appEnvironment?.navigationCoordinator.commentsFrame ?? .zero
|
||||
}
|
||||
// Main window scaling callbacks for interactive drag
|
||||
handler.onMainWindowScaleChanged = { [weak self] progress in
|
||||
guard let self else { return }
|
||||
|
||||
@@ -495,6 +495,23 @@ struct FloatingDetailsPanel: View {
|
||||
}
|
||||
.opacity(expanded ? 1 : 0)
|
||||
.allowsHitTesting(expanded)
|
||||
.background(
|
||||
GeometryReader { commentsGeometry in
|
||||
Color.clear
|
||||
.onChange(of: commentsGeometry.frame(in: .global)) { _, newFrame in
|
||||
if isCommentsExpanded {
|
||||
appEnvironment?.navigationCoordinator.commentsFrame = newFrame
|
||||
}
|
||||
}
|
||||
.onChange(of: isCommentsExpanded) { _, expanded in
|
||||
if expanded {
|
||||
appEnvironment?.navigationCoordinator.commentsFrame = commentsGeometry.frame(in: .global)
|
||||
} else {
|
||||
appEnvironment?.navigationCoordinator.commentsFrame = .zero
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: - Video Info
|
||||
@@ -558,6 +575,7 @@ struct FloatingDetailsPanel: View {
|
||||
}
|
||||
|
||||
private func collapseComments() {
|
||||
appEnvironment?.navigationCoordinator.commentsFrame = .zero
|
||||
// Use same animation as player sheet dismiss (0.3s, no bounce)
|
||||
withAnimation(.smooth(duration: 0.3)) {
|
||||
isCommentsExpanded = false
|
||||
|
||||
@@ -256,6 +256,23 @@ struct PortraitDetailsPanel: View {
|
||||
}
|
||||
.opacity(expanded ? 1 : 0)
|
||||
.allowsHitTesting(expanded)
|
||||
.background(
|
||||
GeometryReader { commentsGeometry in
|
||||
Color.clear
|
||||
.onChange(of: commentsGeometry.frame(in: .global)) { _, newFrame in
|
||||
if isCommentsExpanded {
|
||||
appEnvironment?.navigationCoordinator.commentsFrame = newFrame
|
||||
}
|
||||
}
|
||||
.onChange(of: isCommentsExpanded) { _, expanded in
|
||||
if expanded {
|
||||
appEnvironment?.navigationCoordinator.commentsFrame = commentsGeometry.frame(in: .global)
|
||||
} else {
|
||||
appEnvironment?.navigationCoordinator.commentsFrame = .zero
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
.animation(.smooth(duration: 0.3), value: isCommentsExpanded)
|
||||
.onChange(of: video.id) { _, _ in
|
||||
@@ -521,6 +538,7 @@ struct PortraitDetailsPanel: View {
|
||||
}
|
||||
|
||||
private func collapseComments() {
|
||||
appEnvironment?.navigationCoordinator.commentsFrame = .zero
|
||||
withAnimation(.smooth(duration: 0.3)) {
|
||||
isCommentsExpanded = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user