Onboarding renders as a fixed 292x600 card on Android, not a screen #49
Labels
No labels
needs-info
needs-triage
ready-for-agent
ready-for-human
v2
wayfinder:grilling
wayfinder:map
wayfinder:prototype
wayfinder:research
wayfinder:task
wayfinder:ticket
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
aiko/denpa#49
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Onboarding lays out as a fixed-size card, so on a real Android device it renders as a small
box floating in a large black screen. Observed on both target devices, measured from
screenshots rather than eyeballed.
src/renderer/src/components/receiver/onboarding-spec.ts:44-45:applied at
src/renderer/src/components/receiver/onboarding.tsx:465-468:What it looks like
The card is 292 px on both, so the larger the screen the worse it reads — on the tablet it
occupies just over a third of the width, with the rest empty.
maxWidth="100%"only helps on aviewport narrower than 292 px, which neither device is.
Screenshots:
.denpa-work/shots/phone3.png,.denpa-work/shots/tablet.png.Second defect in the same screen: no safe-area inset
On both devices the onboarding rail renders in the same band as the system status bar, so
待受sits underneath the clock and status icons. The system status bar and the gesture pillcannot be removed and are not the app's to reclaim — onboarding has to lay out around them.
Why it was not caught
#28was built and verified against a browser at a resized window, where a 292 px card inside alarger page is the intended desktop presentation. It was never run on a device. This is the same
shape as
#33: the control looks right, the tests pass, and the thing does not work where itactually runs.
Note that the rest of the chrome does not have this problem.
receiver-chrome.tsxandchrome-spec.tscarry no overall fixed size — only component-level ones (SIDE_KEY_WIDTH,SCANLINE_HEIGHT), and the viewport dispatch inchrome-plan.tsdrives the rest. Onboarding isthe outlier.
Acceptance
the way every other band already is — not by a constant the renderer cannot override.
device.
Related
#28— onboarding, six steps#46— what one unified log looks like at phone width (the same viewport question, one screen over)#48— the ticket this was found underFixed on
mainat688fa2e(merge of856ed03, branchissue/denpa-49-onboarding-fills-viewport).What changed
The card.
SCREEN_WIDTH/SCREEN_HEIGHTare deleted fromonboarding-spec.ts. Onboarding's size is now a row in the same table every band reads:chrome-plan.tsgains anOnboardingPlan { contentMaxWidthPx, padding }onChromePlan— mobilenull, tablet-landscape640(ONBOARDING_MEASURE_PX).use-onboarding.tsmeasures the window with the existinguseViewportand passeschromePlan(viewport).onboardingdown, so the renderer stays a pure render and the window is still read in one place.The root is
position: fixed; inset: 0onground, so the ground is the screen at every size. Only the measure is capped, and only on the wide landscape screen — 640 of 1120 CSS px on the pad, over half the width, rather than a box in the middle of black. The content column scrolls inside the insets rather than the insets scrolling away with it.The status bar. The cause was one line that was not there:
src/renderer/index.htmlhad no viewport meta at all.MainActivity.ktcallsenableEdgeToEdge(), so the WebView is laid out over the status row and the gesture pill — and withoutviewport-fit=covereveryenv(safe-area-inset-*)reports0. That silently disabled the insetsreceiver-chrome.tsx:289-292already reserved, so the chrome had the same defect and nothing failed. The meta is added, and onboarding reserves the four insets the way the chrome's column does.App.tsx's approval overlay, which draws over onboarding, gotmax(16px, env(...))for the same reason.Verified on both devices
Run as the installed debug APK on each device and measured in the app's own WebView over CDP (
webview_devtools_remote,Runtime.evaluate) — live DOM boxes, not a resized browser:env(safe-area-inset-top/bottom)The insets reading non-zero is the proof the meta was the missing piece; the rail's top is below the status row on both, so 待受 no longer sits under the clock.
What I did not do
screencapcame back black on both, and logcat says why — the app's window has no surface while it is not visible (dispatchAppVisibility visible:false,isSurfaceValid:false,SkiaOpenGLPipeline::setSurface: surface=NULL). CDPPage.captureScreenshothangs for the same reason (the target reports"visible": false). It is not caused by this change: the first screencaps, taken before the new APK was running, were black the same way. So "capture it" is met as measurement, not as an image, and eyeballing it on a woken device is still worth doing.cur=2800x2000) but the invisible window was never re-laid out, so the WebView kept reporting 800 x 1120. Landscape is verified at the pad's landscape CSS size (1120 x 800) in a browser instead — root fills 1120 x 800, column 640 centred at x=240 on a full-bleed ground. The device half of that acceptance line is unverified.Gates
npm test— 767 passed, 50 files; 6 new (three inonboarding.test.tsxfor the full-viewport root, the reserved insets and the plan-driven measure; two inchrome-plan.test.ts; one guarding the deleted constants).cargo test— 18 passed.tsc -p tsconfig.web.json— 585 errors, the same 585 asmain, none in the touched files.