Grow the universal NucleicRemote app into a width-adaptive shell so a regular-width iPad renders the macOS sidebar+detail IA while the iPhone keeps its TabView -- both over the same RemoteStore projection (one host authority, N renderers). Phase 1 (adaptive shell): - AdaptiveRootView branches on horizontalSizeClass: CompactRootView (the existing iPhone TabView, moved verbatim) vs SplitRootView (NavigationSplitView) on regular width. - SplitSidebar: Home/Projects/To-dos/Settings destinations + sessions grouped under their projects (attention-sorted), connection chip footer. - SplitDetail selects a destination or a session; a selected session reuses SessionDetailView keyed .id(sessionID) so switching drives open/close. - RemoteStore.closeOpen(_:) is now id-guarded so a split-view A->B switch (onAppear(B) before onDisappear(A)) can't tear down B's fresh subscription. - IdentityStore.deviceID idiom-tags the prefix (ipad-/iphone-) for new installs so the host lists a paired iPad correctly. Phase 2 (width tuning + diff): - readableColumn() caps+centers Home and the transcript on wide layouts; a no-op at phone/portrait width. - SessionDiffView switches on available width (GeometryReader): a Mac-style two-pane diff (file list + selected file's patch) on wide/landscape, the phone stack otherwise. UnifiedPatch splits the combined patch per file. Read-only, same wire, no protocol change. - Demo diff fixture now carries both files' patches. iPhone layout and behavior unchanged. Builds clean; verified in the iPad simulator (demo mode). Co-Authored-By: Claude Opus 4.8 <[email protected]>
13 lines
601 B
Swift
13 lines
601 B
Swift
import SwiftUI
|
|
|
|
/// Width tuning for the universal layout. In a wide iPad detail column, content designed for a
|
|
/// phone runs edge-to-edge and loses the Mac's comfortable reading measure; `readableColumn`
|
|
/// caps its width and centers it. It's a no-op on the phone and on iPad compact multitasking,
|
|
/// where the available width is already below the cap — so the iPhone layout is unchanged.
|
|
extension View {
|
|
func readableColumn(_ maxWidth: CGFloat = 820) -> some View {
|
|
frame(maxWidth: maxWidth, alignment: .leading)
|
|
.frame(maxWidth: .infinity, alignment: .center)
|
|
}
|
|
}
|