@@ -530,22 +530,22 @@ export const ThreadDetailScreen = function ThreadDetailScreen(props: ThreadDetai
530530 const selectedThreadKeyRef = useRef ( selectedThreadKey ) ;
531531 const lastScrolledSubmittedMessageIdRef = useRef < MessageId | null > ( null ) ;
532532 const [ composerExpanded , setComposerExpanded ] = useState ( false ) ;
533- const [ composerFocused , setComposerFocused ] = useState ( false ) ;
534- const handleComposerFocusChange = ( focused : boolean ) => {
535- setComposerFocused ( focused ) ;
536- handleOwnedInputFocusChange ( focused ) ;
537- } ;
538533 const [ anchorMessageId , setAnchorMessageId ] = useState < MessageId | null > ( null ) ;
539534 const [ submittedMessageId , setSubmittedMessageId ] = useState < MessageId | null > ( null ) ;
540535 const [ endFollowEnabled , setEndFollowEnabled ] = useState ( true ) ;
541536 // Android Back hides the keyboard without blurring. Keep its safe-area padding
542537 // fixed through the animation and cancel it with matching composer/list offsets.
543538 const bottomBarInset = useDuoBottomBarInset ( ) ;
539+ // The pill already adds its own gutter; iPad and Duo align its edge with the native bar.
540+ const alignedBottomInset =
541+ bottomBarInset ??
542+ ( Platform . OS === "ios" && Platform . isPad ? Math . max ( insets . bottom , 12 ) : undefined ) ;
543+ // A hardware keyboard can focus the editor without occupying any screen height.
544544 const composerBottomInset =
545- Platform . OS === "ios" && ( composerExpanded || composerFocused )
545+ Platform . OS === "ios" && ( composerExpanded || liveKeyboardHeight > 0 )
546546 ? 0
547- : bottomBarInset !== undefined
548- ? bottomBarInset - THREAD_COMPOSER_BOTTOM_GUTTER
547+ : alignedBottomInset !== undefined
548+ ? Math . max ( 0 , alignedBottomInset - THREAD_COMPOSER_BOTTOM_GUTTER )
549549 : Math . max ( insets . bottom , 12 ) ;
550550 const composerKeyboardOffset = Platform . OS === "android" ? composerBottomInset : 0 ;
551551 const contentPresentationKind = props . contentPresentation . kind ;
@@ -1088,9 +1088,7 @@ export const ThreadDetailScreen = function ThreadDetailScreen(props: ThreadDetai
10881088
10891089 useLayoutEffect ( ( ) => {
10901090 selectedThreadKeyRef . current = selectedThreadKey ;
1091- // A replaced or unmounted native editor may not emit a blur event.
1092- setComposerFocused ( false ) ;
1093- } , [ selectedThreadKey , showContent ] ) ;
1091+ } , [ selectedThreadKey ] ) ;
10941092
10951093 useEffect ( ( ) => {
10961094 setAnchorMessageId ( null ) ;
@@ -1665,7 +1663,7 @@ export const ThreadDetailScreen = function ThreadDetailScreen(props: ThreadDetai
16651663 onUpdateRuntimeMode = { props . onUpdateThreadRuntimeMode }
16661664 onUpdateInteractionMode = { props . onUpdateThreadInteractionMode }
16671665 onExpandedChange = { setComposerExpanded }
1668- onEditorFocusChange = { handleComposerFocusChange }
1666+ onEditorFocusChange = { handleOwnedInputFocusChange }
16691667 />
16701668 </ >
16711669 ) }
0 commit comments