UNPKG

stream-chat-react-native-core

Version:

The official React Native and Expo components for Stream Chat, a service for building chat applications

57 lines (44 loc) 1.86 kB
import { useEffect, useRef } from 'react'; import { EventSubscription, Keyboard, Platform } from 'react-native'; import { useStableCallback } from './useStableCallback'; import { useMessageInputContext } from '../contexts/messageInputContext/MessageInputContext'; /** * A utility hook that returns a stable callback which focuses the message input * and invokes the callback once the keyboard is open. * * @param callback - callback we want to run once the keyboard is ready * @returns A stable callback that will wait for the keyboard to be open before executing. */ export const useAfterKeyboardOpenCallback = <T extends unknown[]>( callback: (...args: T) => void, ) => { const { inputBoxRef } = useMessageInputContext(); const keyboardSubscriptionRef = useRef<EventSubscription | undefined>(undefined); // This callback runs from a keyboard event listener, so it must stay fresh across rerenders. const stableCallback = useStableCallback(callback); /** Clears the pending keyboard listener, if any. */ const clearKeyboardSubscription = useStableCallback(() => { keyboardSubscriptionRef.current?.remove(); keyboardSubscriptionRef.current = undefined; }); useEffect(() => clearKeyboardSubscription, [clearKeyboardSubscription]); return useStableCallback((...args: T) => { clearKeyboardSubscription(); const runCallback = () => { clearKeyboardSubscription(); stableCallback(...args); }; if (!inputBoxRef.current) { runCallback(); return; } if (Keyboard.isVisible()) { inputBoxRef.current.focus(); runCallback(); return; } const keyboardEvent = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow'; keyboardSubscriptionRef.current = Keyboard.addListener(keyboardEvent, runCallback); inputBoxRef.current.focus(); }); };