mirror of
https://github.com/block/buzz.git
synced 2026-11-06 09:21:45 +00:00
## Summary A keyboard raised by a route above (the Add members sheet, search, a native picker) changes the app's `MediaQuery` on every animation frame. Covered pages that read `MediaQuery` directly or through a `Scaffold` rebuilt and relaid out all their content for keyboard motion they cannot show. On #4things, typing in Add members rebuilt every visible message of the channel page underneath for each keyboard frame. `CoveredRouteKeyboardInsets` holds a page's `viewInsets` and `padding` at their last values from when its route was current, while the route is covered. Every other `MediaQueryData` field passes through. A covered page still follows the keyboard down, so when a covering route takes focus and the page's own keyboard closes, the page lowers behind the scrim. A size change (rotation) drops the held values so safe-area padding stays right. When the route becomes current again with the keyboard still above the held value, the page keeps the held values rather than jumping up and riding the keyboard back down. It switches to live values once the keyboard reaches the held value, or as soon as focus is inside the route (the page raised its own keyboard). Otherwise the live values return. It always returns the same widget shape, so covering a page never remounts it. Home, search, the channel page and channel details use it. ## Measurements iPhone 12 mini, Profile build, Builderlab #4things (1,361 members). Flow: open the channel, open its details, tap Add members, tap the search field, then type "chris" one character per second. The window is the 10 s of typing, keyboard included. Both builds also contain the fixes from [#8928](https://github.com/block/buzz/pull/8928), [#8929](https://github.com/block/buzz/pull/8929) and [#8931](https://github.com/block/buzz/pull/8931). | | Before | After | | --- | --- | --- | | UI frame time, total | 3,344 ms | 383 ms | | Frames over 16.7 ms | 101 of 232 | 2 of 297 | | Median / p90 frame | 14.1 / 26.1 ms | 0.6 / 2.0 ms | | UI isolate CPU samples (1 ms) | 2,793 | 868 | | Samples in `MessageContent.build` | 621 | 0 | Single runs per side, not repeated. ## Testing - New widget tests: a covered page doesn't rebuild for keyboard frames and gets the live insets back when it's current again. A current page follows the keyboard. Covering a page keeps its state. A page uncovered with the keyboard still up does not jump, and follows the keyboard once it reaches the held value. A page whose own field takes focus after being uncovered follows the keyboard immediately. A covered page follows its own keyboard closing and takes new padding when rotated. The last test fails (3 mounts instead of 1) against a version that returned a different widget tree when covered. - `just mobile-check mobile-test` passes. - On the phone: Add members search, typing and results behave as before. The channel page and search still move above the keyboard when they're current. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Tom Brow <tomb@squareup.com> Co-authored-by: Tom Brow <tomb@squareup.com> Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@buzz.block.builderlab.xyz> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@localhost>