@@ -15,7 +15,12 @@ import {
1515 Keyboard ,
1616 Platform ,
1717} from 'react-native' ;
18- import type { SharedValue } from 'react-native-reanimated' ;
18+ import Animated , {
19+ Easing ,
20+ LinearTransition ,
21+ withTiming ,
22+ type SharedValue ,
23+ } from 'react-native-reanimated' ;
1924import { type PasteEventPayload , TextInputWrapper } from 'expo-paste-input' ;
2025import AttachmentSheet from '../bottomSheets/AttachmentSheet' ;
2126import { useAttachment , Attachment } from '../../hooks/useAttachment' ;
@@ -33,6 +38,11 @@ import AttachmentThumbnail from './AttachmentThumbnail';
3338import { AudioManager } from 'react-native-audio-api' ;
3439import Toast from 'react-native-toast-message' ;
3540
41+ const BAR_GROW_DURATION = 200 ;
42+ const BAR_GROW_EASING = Easing . out ( Easing . ease ) ;
43+ const BAR_GROW_LAYOUT =
44+ LinearTransition . duration ( BAR_GROW_DURATION ) . easing ( BAR_GROW_EASING ) ;
45+
3646interface Props {
3747 chatId : number | null ;
3848 onSend : (
@@ -94,6 +104,7 @@ const ChatBar = ({
94104 } = useAttachment ( ) ;
95105
96106 const defaultBarHeight = useRef ( 0 ) ;
107+ const prevBarHeight = useRef ( 0 ) ;
97108 const textInputRef = useRef < RNTextInput > ( null ) ;
98109 // iOS-only: bump the TextInput key to force a remount when a prompt
99110 // suggestion is set programmatically. iOS doesn't re-fire onLayout
@@ -136,9 +147,16 @@ const ChatBar = ({
136147 }
137148 const baseline = defaultBarHeight . current || height ;
138149 const delta = height - baseline ;
139- extraContentPadding . set ( Math . max ( 0 , delta ) ) ;
150+ extraContentPadding . set (
151+ withTiming ( Math . max ( 0 , delta ) , {
152+ duration : BAR_GROW_DURATION ,
153+ easing : BAR_GROW_EASING ,
154+ } )
155+ ) ;
140156 onHeightChange ?.( height ) ;
141- if ( delta > 0 ) {
157+ const grew = height > prevBarHeight . current ;
158+ prevBarHeight . current = height ;
159+ if ( delta > 0 && grew ) {
142160 onBarGrow ?.( ) ;
143161 }
144162 } ,
@@ -266,7 +284,11 @@ const ChatBar = ({
266284 }
267285
268286 return (
269- < View style = { containerStyle } onLayout = { handleBarLayoutForPadding } >
287+ < Animated . View
288+ style = { containerStyle }
289+ onLayout = { handleBarLayoutForPadding }
290+ layout = { BAR_GROW_LAYOUT }
291+ >
270292 { model ?. isDownloaded && (
271293 < >
272294 { ! hasMessages && (
@@ -330,7 +352,7 @@ const ChatBar = ({
330352 />
331353 </ >
332354 ) }
333- </ View >
355+ </ Animated . View >
334356 ) ;
335357} ;
336358
@@ -382,7 +404,9 @@ const createStyles = (theme: Theme) =>
382404 fontSize : fontSizes . md ,
383405 // lineHeight on Android causes typed text to be taller than the
384406 // placeholder, making the ChatBar jump on first keystroke.
385- ...( Platform . OS === 'ios' && { lineHeight : lineHeights . md } ) ,
407+ ...( Platform . OS === 'ios'
408+ ? { lineHeight : lineHeights . md }
409+ : { includeFontPadding : false } ) ,
386410 fontFamily : fontFamily . regular ,
387411 textAlignVertical : 'center' ,
388412 color : theme . text . onChatBar ,
0 commit comments