diff --git a/ANDROID.md b/ANDROID.md index 6d7ade2..61391ea 100644 --- a/ANDROID.md +++ b/ANDROID.md @@ -68,6 +68,37 @@ transform (the small art flies to the big one). The player's scrubber is the lane itself, no knob. Motion is Material 3 Expressive's springs, sampled into `linear()`. Reduce motion (You → Appearance, or the OS setting) turns it off. +The activity declares no `screenOrientation` and handles `orientation` and +`screenSize` itself, so turning the phone over is a resize and nothing else — +the audio thread, the stack and the screen's scroll all survive it, and the +layout is the only thing that has to answer. Two media queries do that. The +player sheet is the one surface whose portrait shape cannot survive a wide +viewport: its artwork is a square sized by WIDTH, so at 915×411 the cover came +out 879px tall and the title, the lane, the transport and the face buttons sat +below the bottom of a sheet that does not scroll — a corner of the cover and no +way to pause. Sideways it is two columns: the head across the top, the cover +down the left sized by HEIGHT, and the track, the scrubber, the transport and +the faces stacked on the right. With lyrics or the queue up, the face takes the +cover's column and the thumbnail goes — the record is already the ground behind +the whole sheet. That is an aspect problem rather than a height one, so the rule +keys off `orientation: landscape` alone and a tablet gets the same two columns. + +The rest is a phone-sized query (`max-height: 560px`). The nav comes down to +Android's own 48dp minimum and the mini bar to a 60dp row over the same lane +strip, which gives the page back 22 of a 411-pixel screen — the chrome was 46% +of the height, it is 40%. The artist hero stops being a 300px portrait, which +covered its own Play button with the mini bar, and becomes a 190px banner: what +the desktop's hero has always been. The record head puts the cover beside the +title rather than above it, again the desktop's own shape, so Play is in view +without a scroll. A half sheet may take all but 36px of the height instead of +76% of it. Everything else — the grids, the rails, the artwork viewer, the +tap-to-sync room, the chat composer — already answered to width and was left +alone. `viewport-fit=cover` means the cutout and the gesture pill come in from +the SIDES in landscape, so the shell reads `--inset-left` / `--inset-right` +beside the top and bottom ones now. Those rules are appended at the end of +`shell.css` on purpose: they have to come after `.gbar`'s padding, `.mini`'s +and `.toast`'s left/right to win at equal specificity. + ## Search and the resolver Search is the desktop's top bar: the field asks the **catalog** once the @@ -631,14 +662,20 @@ a catalog card's and the record page's sheets → the now-playing Save → a peer's sheet, a raw file's sheet, a user's shares browsed and a folder of theirs streamed → a buddy's sheet → You (every switch and chip saved and read back from the config) → recent searches and a spelling -suggestion → the sleep timer, asserts what each step should show, screenshots every step into `tests/mobile/out/`, and fails on +suggestion → the sleep timer → the phone turned sideways (the player's three faces, a +record with a long sheet over it, an artist page, and the side insets faked, +all at 915×411) and back, asserts what each step should show, screenshots every step into `tests/mobile/out/`, and fails on any exception or console error. The mock answers every command the phone uses; one it does not know is named in the report (`[mock] no mock for X`) rather than surfacing as a TypeError toast, console warnings carry their top frames (the smoke bundle is built unminified for that), and every probe carries the history mirror — the entry's depth against the layers the app says the back gesture can peel (`hd`/`hwant`; a drift is how the blank -page after a confirmed delete was found). +page after a confirmed delete was found). A mock step can also set the +viewport — `{ view: [915, 411] }` sends `Emulation.setDeviceMetricsOverride` +through the same client, which is how the walk turns the phone over and back; +the phone walk refuses one, because a real device's orientation is not the +harness's to set. The phone walk is the same driver on the real thing (plus a step kind of its own: `{ adb: [...] }` runs an adb command — the share-sheet intent, a diff --git a/src/mobile/Sheet.svelte b/src/mobile/Sheet.svelte index 5ab98c5..60f6011 100644 --- a/src/mobile/Sheet.svelte +++ b/src/mobile/Sheet.svelte @@ -141,7 +141,7 @@
-
+