Allow pinch-to-panscan on the video in the corner layout

The window-level pinch was blocked whenever the landscape panel was
pinned and visible (the corner layout always counts as pinned) or a
stale portrait-panel flag was set. In the corner layout the pinch now
starts when it begins inside the video region, and the panscan
control button is enabled there too.
This commit is contained in:
Arkadiusz Fal
2026-10-20 23:43:47 +02:00
parent b98cc216ad
commit e276c99d0b
3 changed files with 37 additions and 1 deletions

View File

@@ -1373,6 +1373,19 @@ extension ExpandedPlayerSheet {
fullWidth: width,
fullHeight: height
)
#if os(iOS)
.background {
GeometryReader { proxy in
Color.clear
.onChange(of: proxy.frame(in: .global), initial: true) { _, frame in
navigationCoordinator?.cornerVideoFrame = frame
}
.onDisappear {
navigationCoordinator?.cornerVideoFrame = .zero
}
}
}
#endif
},
onChannelTap: video.author.hasRealChannelInfo ? {
navigationCoordinator?.navigateToChannel(for: video, collapsePlayer: true)
@@ -1686,7 +1699,10 @@ extension ExpandedPlayerSheet {
playerService.selectEmbeddedSubtitleTrack(trackID)
},
panscanValue: navigationCoordinator?.pinchPanscan ?? 0.0,
isPanscanAllowed: !(isPanelPinned && isPanelVisible),
// Corner layout: the video owns its own region, so it can
// fill it even with the panels showing
isPanscanAllowed: !(isPanelPinned && isPanelVisible)
|| appEnvironment?.navigationCoordinator.isCornerLayoutActive == true,
onTogglePanscan: { [weak navigationCoordinator] in
navigationCoordinator?.togglePanscan()
},

View File

@@ -180,6 +180,10 @@ private final class DragToDismissGestureHandler: NSObject, UIGestureRecognizerDe
var getPortraitPanelFrame: (() -> CGRect)?
/// Returns the corner layout below-video panel frame in screen coordinates (blocks dismiss pan)
var getCornerBelowPanelFrame: (() -> CGRect)?
/// Returns true while the corner layout is active (its panels don't block pinch)
var isCornerLayoutActive: (() -> Bool)?
/// Returns the corner layout video region frame in screen coordinates (pinch must start inside it)
var getCornerVideoFrame: (() -> CGRect)?
/// Returns the panel resize grabber strip frame in screen coordinates (blocks dismiss pan)
var getPanelResizeGrabberFrame: (() -> CGRect)?
var getPlayerSideSliderFrames: (() -> [CGRect])?
@@ -356,6 +360,12 @@ private final class DragToDismissGestureHandler: NSObject, UIGestureRecognizerDe
// Don't allow pinch gesture when pinned panel is visible on screen or seek gesture is active
if gestureRecognizer is UIPinchGestureRecognizer {
if isSeekGestureActive?() == true { return false }
// Corner layout: the video sits in its own region beside the
// panels, so pinching it is fine — but not over the panels
if isCornerLayoutActive?() == true {
let videoFrame = getCornerVideoFrame?() ?? .zero
return videoFrame.isEmpty || videoFrame.contains(gestureRecognizer.location(in: nil))
}
if isPortraitPanelVisible?() == true { return false }
return !(isPanelPinnedAndVisible?() ?? false)
}
@@ -883,6 +893,12 @@ final class ExpandedPlayerWindowManager {
handler.getCornerBelowPanelFrame = { [weak self] in
self?.appEnvironment?.navigationCoordinator.cornerBelowPanelFrame ?? .zero
}
handler.isCornerLayoutActive = { [weak self] in
self?.appEnvironment?.navigationCoordinator.isCornerLayoutActive ?? false
}
handler.getCornerVideoFrame = { [weak self] in
self?.appEnvironment?.navigationCoordinator.cornerVideoFrame ?? .zero
}
handler.getPanelResizeGrabberFrame = { [weak self] in
self?.appEnvironment?.navigationCoordinator.panelResizeGrabberFrame ?? .zero
}