Rework corner layout with portrait-style info panel below the video

The corner layout now always renders the info page as a portrait-style
panel below the video (collapsible description, drag to hide/expand),
while the side column holds tabs for the remaining pages. Key pieces:

- Below-video panel reuses PortraitDetailsPanel (no comments pill,
  square corners, chapters/related stay in the side column tabs)
- Drag down hides the panel with the video recentering in lockstep;
  swipe up on the video reveals it following the finger
- Fullscreen button toggles the panels in corner layout (controls hide
  first so their resize never plays visibly); status bar and home
  indicator hide only while the panels are hidden
- Panel visibility and column width are seeded at init from a warmed
  PlayerControlsLayout cache, so the first frame resolves corner mode
  without flashing the default layout or animating the panels in
- Dismiss pan is blocked inside the below-video panel frame
  (cornerBelowPanelFrame in NavigationCoordinator)
- Resize grabber slimmed to match the panel drag handle look
This commit is contained in:
Arkadiusz Fal
2026-09-23 07:25:02 +02:00
parent ec13fda115
commit 05a03723f6
14 changed files with 586 additions and 435 deletions

View File

@@ -106,6 +106,12 @@ struct PlayerControlsLayout: Codable, Hashable, Sendable {
// MARK: - Defaults
/// Last loaded active layout — lets the expanded player seed its layout
/// state synchronously before the async load, so the first frames resolve
/// the correct layout (e.g. corner mode) instead of flashing the default.
/// Warmed at app start and kept fresh by the expanded player's loads.
nonisolated(unsafe) static var cached: PlayerControlsLayout = .default
/// Default layout matching the current hardcoded player controls.
static let `default`: PlayerControlsLayout = {
// Top section: spacer, brightness (widescreen), volume, airplay, debug, close