Skip to content

fix(chat): account for input padding so the second line is visible - #716

Merged
islandbitcoin merged 4 commits into
mainfrom
fix/chat-composer-grow
Aug 31, 2026
Merged

fix(chat): account for input padding so the second line is visible#716
islandbitcoin merged 4 commits into
mainfrom
fix/chat-composer-grow

Conversation

@islandbitcoin

Copy link
Copy Markdown
Contributor

Fixes #715 (found live in the Flash Support chat). The composer's grow logic set box height to contentSize.height, which excludes the 16px vertical padding — so two lines of content (~38px) still clamped to MIN_HEIGHT 40 and the second line rendered under the padding. The padding is now added before clamping. One component serves both the DM screen and SupportGroupChat. 7-line diff; needs a quick device look since composer height is a visual behavior no unit test sees.

Dread and others added 4 commits August 31, 2026 10:58
)

The composer already grows via onContentSizeChange, but it set the box
height to the reported CONTENT height, which excludes the input's 16px
of vertical padding. One line (~20px) clamps up to MIN_HEIGHT 40 and
looks fine; two lines (~38px) STILL clamp to 40, so the second line
renders underneath the padding -- you type it but never see it. Found
live by Jabari in the Flash Support chat.

Add the padding to the measurement before clamping. MessageInput is the
composer for both the DM screen and SupportGroupChat, so one fix covers
both surfaces.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEoz7nBtdtsHyuYG5wNPQV
…tant and tests

Review fixes for #716:
- Extract pure computeComposerHeight into composer-height.ts and cover it
  with jest tests, including the #715 two-line regression case (38 -> 54).
- Single source of truth for the input's vertical padding: INPUT_PADDING_V
  is used by both the stylesheet and the grow math, replacing the
  'keep in sync' comment.
- Rename MIN/MAX_HEIGHT to MIN/MAX_BOX_HEIGHT and document that they bound
  the rendered box including padding, so the scroll threshold semantics
  are explicit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEoz7nBtdtsHyuYG5wNPQV
Device findings on #716, both real:

iOS: the composer visibly oscillated -- grow, snap back, grow. The
controlled-height mechanism WAS the bug: this app runs the New
Architecture, and Fabric auto-sizes multiline TextInputs natively, so
driving height from onContentSizeChange through state triggers relayout,
which reports a new content size, which sets a new height. The fix
removes the mechanism entirely: height is never set, the box is bounded
by minHeight/maxHeight styles, the input grows natively (which also
fixes #715 by construction) and scrolls internally past the max.
composer-height.ts keeps only the constants; the spec now pins the
MECHANISM -- asserts onContentSizeChange and a controlled height are
absent, and the min/max bounds present -- because the arithmetic it used
to test no longer runs anywhere.

Android: the keyboard covered the composer. This app targets SDK 35, so
Android 15+ enforces edge-to-edge and IGNORES the manifest's
adjustResize -- and the Screen wrapper's KeyboardAvoidingView only sets
a behavior on iOS, historically leaning on adjustResize for Android.
Verified on the test device (Pixel, Android 15+). New
use-keyboard-padding hook: Android-only keyboard listeners pad the
composer wrapper by the keyboard height, falling back to the safe-area
inset when closed. iOS deliberately returns 0 -- Screen's
behavior="padding" already moves content there, and stacking both would
double-shift.

Wired into both chat surfaces (messages.tsx, SupportGroupChat.tsx).
94 suites / 917 tests green, tsc clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEoz7nBtdtsHyuYG5wNPQV
Device re-test: iOS correct, Android improved but the composer still sat
under Gboard's suggestion strip. Root cause of the shortfall: the strip
appears AFTER keyboardDidShow fires, and the IME grows without emitting
another event -- so an event-driven padding is structurally ~50px short
whenever suggestions render.

Replaced the Keyboard.addListener hook with Reanimated's
useAnimatedKeyboard (already a dependency, no new native module): it
reads the IME window insets continuously on the UI thread, so the
padding tracks every height change including the strip appearing and
disappearing mid-typing. Translucent-bar options set to match the app's
edge-to-edge window; option names verified against the installed 3.18.2
typings. iOS still contributes zero padding -- Screen's
KeyboardAvoidingView behavior="padding" owns that platform, and user
confirmed iOS renders correctly.

Both chat surfaces wrapped in Animated.View driven by the shared style.

94 suites / 917 tests green, tsc + lint clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEoz7nBtdtsHyuYG5wNPQV
@islandbitcoin
islandbitcoin merged commit 14d0089 into main Aug 31, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chat input box does not grow — second line is hidden while typing

1 participant