From a2ee7d536373041029d4c7b9e48c3411ab5a9022 Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Tue, 13 Oct 2026 19:01:43 +0200 Subject: [PATCH] Keep the player pill off the hinge in book posture On a foldable with the hinge partially open, the corner layout's player pill moves to the center of the trailing half while the side column is hidden. It slides with the column as it is dragged away or revealed, keeping its width. --- Yattee/Views/Player/CornerPlayerLayout.swift | 17 +++++++++++++++-- Yattee/Views/Player/PortraitDetailsPanel.swift | 5 +++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Yattee/Views/Player/CornerPlayerLayout.swift b/Yattee/Views/Player/CornerPlayerLayout.swift index 2f455ad4..1c70e4e5 100644 --- a/Yattee/Views/Player/CornerPlayerLayout.swift +++ b/Yattee/Views/Player/CornerPlayerLayout.swift @@ -265,6 +265,13 @@ struct CornerPlayerLayout: View { let sideColumnSlide = hasSideColumnLayout ? min(sideColumnHideTravel, max(0, sideColumnDragOffset)) : 0 let columnVideoWidth = hasSideColumnLayout ? min(width, shownVideoWidth + sideColumnSlide) : width let videoWidth = isPanelVisible ? columnVideoWidth : width + // Hinge split: as the column hides, the below panel widens over + // the fold, so its pills slide from the leading half's center to + // the trailing half's in lockstep with the column (and back on + // reveal). The pills' width (panel width minus inset) stays half + // the screen throughout. + let sideColumnHiddenProgress: CGFloat = hasSideColumnLayout ? sideColumnSlide / max(1, sideColumnHideTravel) : 1 + let hingePillsLeadingInset: CGFloat = isHingeSplit ? width / 2 * sideColumnHiddenProgress : 0 let shownVideoHeight: CGFloat = { let rawAspectRatio = playerState?.displayAspectRatio ?? (16.0 / 9.0) let aspectRatio = rawAspectRatio > 0 ? rawAspectRatio : (16.0 / 9.0) @@ -414,7 +421,12 @@ struct CornerPlayerLayout: View { Spacer(minLength: 0) .frame(height: panelSpacerHeight) - belowVideoInfoPanel(video: video, hideTravel: panelHideTravel, publishesFrame: showsBelowVideo) + belowVideoInfoPanel( + video: video, + hideTravel: panelHideTravel, + publishesFrame: showsBelowVideo, + pillsLeadingInset: hingePillsLeadingInset + ) .frame(width: columnVideoWidth) .frame(height: panelHeight) .offset(y: belowPanelSlide) @@ -642,7 +654,7 @@ struct CornerPlayerLayout: View { /// pill hidden and no inline chapters/related — those live in the side /// column tabs. @ViewBuilder - private func belowVideoInfoPanel(video: Video, hideTravel: CGFloat, publishesFrame: Bool) -> some View { + private func belowVideoInfoPanel(video: Video, hideTravel: CGFloat, publishesFrame: Bool, pillsLeadingInset: CGFloat) -> some View { Group { #if os(iOS) PortraitDetailsPanel( @@ -653,6 +665,7 @@ struct CornerPlayerLayout: View { hidesCommentsPill: !hasBelowVideoComments, inlineInfoSections: false, panelCornerRadius: 0, + pillsLeadingInset: pillsLeadingInset, onDragChanged: { offset in if appEnvironment?.navigationCoordinator.isPanelDragging != true { appEnvironment?.navigationCoordinator.isPanelDragging = true diff --git a/Yattee/Views/Player/PortraitDetailsPanel.swift b/Yattee/Views/Player/PortraitDetailsPanel.swift index 8b4d9e89..b024eb6f 100644 --- a/Yattee/Views/Player/PortraitDetailsPanel.swift +++ b/Yattee/Views/Player/PortraitDetailsPanel.swift @@ -30,6 +30,10 @@ struct PortraitDetailsPanel: View { /// Panel clip rounding — the corner layout's below-video host uses 0 /// for a plain rectangle. var panelCornerRadius: CGFloat = 16 + /// Moves the pills off the leading part of the panel (foldable book + /// posture with the side column hidden: pills centered on the half right + /// of the hinge). + var pillsLeadingInset: CGFloat = 0 // Drag gesture callbacks var onDragChanged: ((CGFloat) -> Void)? @@ -240,6 +244,7 @@ struct PortraitDetailsPanel: View { .overlay { if !isCommentsExpanded { pillsOverlay + .padding(.leading, pillsLeadingInset) .opacity(pillsOverlayOpacity) .allowsHitTesting(pillsOverlayOpacity > 0.01) }