Repository navigation
Conversation
added 3 commits
October 1, 2026 13:52
The iOS sample targeted iOS 18, so DuoHingeSource gated every Duo type behind #available(iOS 27.1, *) and passed UIHinge around as Any? to keep it out of ungated call sites. No system before 27.1 has a hinge to report, so the gates only cost readability. With the deployment target at 27.1 the source uses UIHinge directly. README and CLAUDE.md now describe the 27.1 target. The README keeps the #available advice for apps that copy the file and support older systems.
The first player used emoji glyphs for transport buttons and a plain queue, so it showed the pane shapes but didn't look like a player anyone ships. It now follows the usual streaming-app pattern: a video stage with an overlay (minimise, captions, more, seek ±10 s, scrubber, full screen) that hides itself while playing, an "Up next" queue with thumbnails, durations and per-episode progress, and episode details with a speed chip. The fold still decides the arrangement. Book or a wide window puts the video and details beside the queue, Tabletop moves the scrubber, transport controls, speed and captions to the flat half, and a single pane stacks video, details and queue in one list. PlayerIcons holds the handful of Material icons as path data, because the icons artifact is no longer published for Compose Multiplatform. Checked on the Pixel Fold and Pixel 10 emulators and on the iPhone Duo simulator in Book, Open, rotated Flat, Tabletop and Closed.
On the iPhone Duo, the camera housing is a corner region ([585,0,669,120] on a 669x951 window). occlusionInsets() treated any region touching the right edge as right-only, so the housing padded the whole right edge by 84pt and left an empty strip down the Notes and Player screens. A region touching two edges now pads only the cheaper one. rememberOcclusionPadding() takes a reserved PaddingValues: a region that padding already clears adds nothing, and otherwise the result covers only the remainder, so it stacks with the caller's own padding. The sample passes its content padding, whose top bar clears the housing.
…ndow DuoHingeSource attached its hinge interaction and rotation observer once, in begin(). If there was no key window yet, both were skipped and nothing tried again, so an app that started observing before its window existed stayed on Unknown with no error. The didBecomeActive observer now also attaches whatever is still missing. Checked on the Duo by skipping the first attach: the activation retry attached both and the hinge handler published the half-open status. derivePosture fell back to Book for a half-open hinge with no active division region, on the claim that the Duo's hinge is vertical in portrait. The rotation logs show the opposite: the tall 669x951 window is portrait and its fold is horizontal. The fallback now takes the axis from the window's shape, so a tall window reads Tabletop and a wide one Book.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four commits on top of
main.Corner occlusion padding (
hinge-compose). On the iPhone Duo the camera housing is a corner region ([585,0,669,120]on a 669×951 window).occlusionInsets()treated any region touching the right edge as right-only, so it padded the whole right edge by 84pt and left an empty strip down the Notes and Player screens. A region touching two edges now pads only the cheaper one, andrememberOcclusionPadding()takes areservedPaddingValues: a region that padding already clears adds nothing, otherwise the result covers only the remainder. The sample passes its content padding, whose top bar clears the housing.OcclusionInsetsTestcovers both corner cases.Player screen. Replaces the emoji controls and plain queue with a streaming-app layout: an overlay on the video that hides while playing, an Up next list with thumbnails and progress, and episode details with a speed control. Book puts the player and details on one side of the fold and Up next on the other; Tabletop puts the video on the raised half and the controls on the flat half; single-pane windows scroll everything in one column. Icons live in
PlayerIconsas path data.iOS 27.1 deployment target. The sample now targets the first release with the Duo APIs, so
DuoHingeSource.swiftdrops its#availablechecks and theAny?workaround.iOS bridge fixes.
DuoHingeSourcenow retries attaching the hinge interaction and rotation observer ondidBecomeActive, so observing before the window exists no longer leaves the posture on Unknown. A half-open hinge with no active division region now takes its axis from the window's shape (tall reads Tabletop, wide reads Book); the old fallback always picked Book, though the Duo's tall window is portrait with a horizontal fold.:hinge-core:allTests,:hinge-compose:iosSimulatorArm64Testand:sample:android-app:assembleDebugpass locally, and the iOS app builds against the Xcode 27.1 SDK.