···226226 const keyboardHeight = useSharedValue(0)
227227 const keyboardIsOpening = useSharedValue(false)
228228229229+ // In some cases - like when the emoji piker opens - we don't want to animate the scroll in the list onLayout event.
230230+ // We use this value to keep track of when we want to disable the animation.
231231+ const layoutScrollWithoutAnimation = useSharedValue(false)
232232+229233 useKeyboardHandler({
230230- onStart: () => {
234234+ onStart: e => {
231235 'worklet'
232232- keyboardIsOpening.value = true
236236+ // Immediate updates - like opening the emoji picker - will have a duration of zero. In those cases, we should
237237+ // just update the height here instead of having the `onMove` event do it (that event will not fire!)
238238+ if (e.duration === 0) {
239239+ layoutScrollWithoutAnimation.value = true
240240+ keyboardHeight.value = e.height
241241+ } else {
242242+ keyboardIsOpening.value = true
243243+ }
233244 },
234245 onMove: e => {
235246 'worklet'
···277288278289 // -- List layout changes (opening emoji keyboard, etc.)
279290 const onListLayout = React.useCallback(() => {
280280- if (keyboardIsOpening.value) return
281291 if (isWeb || !keyboardIsOpening.value) {
282282- flatListRef.current?.scrollToEnd({animated: true})
292292+ flatListRef.current?.scrollToEnd({
293293+ animated: !layoutScrollWithoutAnimation.value,
294294+ })
295295+ layoutScrollWithoutAnimation.value = false
283296 }
284284- }, [flatListRef, keyboardIsOpening.value])
297297+ }, [flatListRef, keyboardIsOpening.value, layoutScrollWithoutAnimation])
285298286299 const scrollToEndOnPress = React.useCallback(() => {
287300 flatListRef.current?.scrollToOffset({