Repository navigation
Show chapters and bookmarks beside the player on iPhone Duo - #1640
GianniCarlo wants to merge 4 commits into
Conversation
… Duo On iOS 27.1 the player is the primary side of an ArrangementView whose secondary side is a panel with the chapters and bookmarks, switched with a segmented control. ArrangementView shows it when there's room: the open iPhone Duo in landscape, split on the fold when half-folded. Closed, or open in portrait, the player is alone as before. In the panel the lists have no close button and picking a row doesn't dismiss. The chapters checkmark follows playback and the bookmarks reload after any save that touches one, so both stay current while on screen. The player's list button hides while the panel shows. CI moves to Xcode 27.1, which has the iOS 27.1 SDK.
🟡 Claude PR Review —
|
| Finding | Status |
|---|---|
BookPlayer/Player/Views/PlayerView.swift:142 (info) ⚠︎ moved |
🟡 still open |
Model claude-opus-5-5 · run log · 0 new · 1 carried over · 1 re-worded on their own thread · 0 resolved · advisory (a human should still review). Findings are de-duplicated across pushes; an earlier finding closes only when the verification pass judges it against the current code — fixed, no longer applicable, accepted by a maintainer, or a duplicate of a finding reported on this push.
- More no longer offers the chapters or bookmarks while the panel shows them. PlayerView reads whether the panel shows once and passes it to the button row and the More menu. - The chapters list scrolls to the new chapter only while the playing chapter's row is on screen, so it doesn't jump away from chapters someone is browsing. - BookmarksViewModelTests cover the reload: a save touching a bookmark reloads the list, a save touching other entities doesn't.
|
On the findings without an inline thread:
|
| /// the screen's full width | ||
| buttonSpacing: isSideBySide ? 24 : nil, | ||
| /// The panel beside the player already shows the lists this button opens | ||
| showsListButton: !isPanelShown, |
There was a problem hiding this comment.
🔵 INFO — The list button and More entry now hide while the panel shows. But a Chapters or Bookmarks sheet opened before the panel appeared stays up and covers both sides. For example: open Chapters in portrait on an open Duo, then rotate to landscape. Consider calling viewModel.hideSheet() when the panel appears and sheetStyle is .chapters or .bookmark, e.g. with an .onChange(of: isPanelShown) inside the PlayerListPanelReader closure.
There was a problem hiding this comment.
Leaving as is: the sheet still closes normally, and portrait on the open Duo gets its own layout in a follow-up PR.
There was a problem hiding this comment.
Reported again on the newest commit, worded differently — the current wording is:
The list button and the More entry now hide while the panel shows. But a Chapters or Bookmarks sheet opened before the panel appeared stays up and covers both sides. Example: open Chapters in portrait on an open Duo, then rotate to landscape. Consider calling viewModel.hideSheet() when the panel appears and sheetStyle is .chapters or .bookmark, e.g. with an .onChange(of: isPanelShown) inside the PlayerListPanelReader closure.
Following playback pulled the list away from chapters someone was browsing. Tracking which rows are on screen to avoid that wasn't reliable (the list drops some "row left the screen" events during a fling), and the visibility modifier also kept the rows' background from reaching the list. The list scrolls to the playing chapter when it opens, as before; the checkmark still moves with playback.
|
On the remaining notes:
|
| @@ -13,10 +13,10 @@ jobs: | |||
| timeout-minutes: 30 | |||
| steps: | |||
There was a problem hiding this comment.
🟡 WARN — This makes Xcode 27.1 a hard requirement for develop: ArrangementView exists only in the iOS 27.1 SDK, and #available doesn't help at compile time. The PR says 27.1 is still in beta ("once 27.1 is out of beta"), and App Store Connect rejects builds made with a beta Xcode. Once this merges, no release can be cut from develop until 27.1 ships and Xcode Cloud is switched to it.
Options:
- hold the merge until 27.1 is final, or
- guard
PlayerListPanelModifier/SplitAxisReaderwith#if compiler(>=…)or an SDK check, so the code still builds with 27.0 and only turns the panel on with 27.1.
Also add this to the release checklist, not only the PR description.
There was a problem hiding this comment.
Reported again on the newest commit, worded differently — the current wording is:
This still makes Xcode 27.1 a hard requirement for develop. PlayerListPanelModifier uses ArrangementView / .arrangementViewStyle(.split…) behind #available(iOS 27.1, *) only. That is a runtime check, so Xcode 27.0 can't compile the file. If 27.1 is still in beta, App Store Connect won't accept builds from it, and no release can be cut from develop until 27.1 ships and Xcode Cloud moves to it.
Options:
- hold the merge until 27.1 is final, or
- wrap the
ArrangementViewbranch ofPlayerListPanelModifier.bodyin a compile-time check (#if compiler(>=6.x)for the 27.1 toolchain, or an SDK-version flag) so 27.0 builds still work and just show the player alone.
Also add the Xcode Cloud switch to the release checklist, not only to CLAUDE.md and the PR description.
…their presenters - Drop the panel detection (PlayerListPanelReader, the list button and More entry hidden while the panel shows). SwiftUI can't tell whether ArrangementView shows its secondary side, and splitArrangementAxis reads horizontal on a closed Duo in landscape too, which hid the list button with no panel on screen. Both always show now. - ChaptersView and BookmarksView no longer know where they're shown: no isBesidePlayer, no NavigationStack, close button or dismiss of their own. PlayerView's PlayerListSheet wraps them for the sheets (navigation stack, close button, onSelect closes the sheet after a pick); the panel keeps its own navigation stack with the Chapters | Bookmarks switch, and a pick there leaves it on screen.
Problem
The open iPhone Duo (951 × 669 pt in landscape) gives the player a screen it doesn't use: the one-column player sits in the middle of a wide display, and the chapters and bookmarks are still sheets that cover it.
Changes
PlayerListPanel(new): on iOS 27.1 the player is the primary side of anArrangementView(.split, horizontal only), and the secondary side is a panel with the chapters and bookmarks, switched with a Chapters | Bookmarks segmented control in its navigation bar. It starts on the list Player Controls › Opens picks. Picking a chapter or bookmark jumps and leaves the panel on screen; the player closes from its grabber, as before.ArrangementViewdecides when there's room. Measured on the Duo simulator: closed, or open in portrait, the player is alone and looks as it does today; open in landscape the two sides share the width (433.5 pt each, flat), and half-folded the split moves onto the fold..playerListPanel(...)after the player's button row, so the drag to close and the rounded background cover both sides. Below iOS 27.1 the player is unchanged.ArrangementViewshows its secondary side, and the closest signal,splitArrangementAxis, reads horizontal on a closed Duo in landscape too, where there's no panel.ChaptersView/BookmarksView: no longer know where they're shown. They drop their ownNavigationStack, close button and dismiss; whoever shows them provides those.PlayerView'sPlayerListSheetdoes it for the sheets (navigation stack, close button,onSelectcloses the sheet after a pick), and the panel has its own navigation stack. Reload and share stay in the lists' toolbars, so they show in both.ChaptersViewModel: followscurrentItemPublisher()and the item's$currentChapter, so the checkmark moves with playback and the rows change with the book. The list doesn't scroll when the chapter changes, so it never pulls away from chapters someone is browsing; it scrolls to the playing chapter when it opens, as before. This applies to the sheet too.BookmarksViewModel: reloads after any Core Data save that touches aBookmark(didSaveObjectIDsNotification, object IDs only), so a bookmark made with the player's button, an automatic bookmark or a sync shows up in the panel while it's on screen.ArrangementViewis in the iOS 27.1 SDK only. CLAUDE.md updated.Testing
testFreshLaunch,testImportandtestPlaybackpass (the player opens and plays).ChaptersViewModelTestsstub the player's item publisher and gain two tests, for the checkmark following the chapter and the rows following the book. NewBookmarksViewModelTests: a save touching a bookmark reloads the list, a save touching other entities doesn't.Not covered:
ArrangementViewon other iPhones and iPad. The iOS 27.1 simulator runtime only runs iPhone Duo, so how it lays out there is to check once 27.1 is out of beta.Before the next release: Xcode Cloud's Xcode version (App Store Connect) needs to be 27.1, or the release build won't compile.