@@ -12,13 +12,13 @@ import {
1212 GestureResponderHandlers ,
1313 InteractionManager ,
1414 LayoutAnimation ,
15- SafeAreaView ,
1615 StatusBar ,
1716 StatusBarProps ,
1817 Text ,
1918 View ,
2019} from 'react-native'
2120import ImageView from 'react-native-image-viewing'
21+ import { useSafeAreaInsets } from 'react-native-safe-area-context'
2222
2323import { usePrevious } from '../../hooks'
2424import { l10n } from '../../l10n'
@@ -48,6 +48,8 @@ dayjs.extend(calendar)
4848export type ChatTopLevelProps = InputTopLevelProps & MessageTopLevelProps
4949
5050export interface ChatProps extends ChatTopLevelProps {
51+ /** Allows you to replace the default Input widget e.g. if you want to create a channel view. */
52+ customBottomComponent ?: ( ) => React . ReactNode
5153 /** If {@link ChatProps.dateFormat} and/or {@link ChatProps.timeFormat} is not enough to
5254 * customize date headers in your case, use this to return an arbitrary
5355 * string based on a `dateTime` of a particular message. Can be helpful to
@@ -99,6 +101,7 @@ export interface ChatProps extends ChatTopLevelProps {
99101
100102/** Entry component, represents the complete chat */
101103export const Chat = ( {
104+ customBottomComponent,
102105 customDateHeaderText,
103106 dateFormat,
104107 disableImageGallery,
@@ -145,6 +148,7 @@ export const Chat = ({
145148 const { onLayout, size } = useComponentSize ( )
146149 const animationRef = React . useRef ( false )
147150 const list = React . useRef < FlatList < MessageType . DerivedAny > > ( null )
151+ const insets = useSafeAreaInsets ( )
148152 const [ isImageViewVisible , setIsImageViewVisible ] = React . useState ( false )
149153 const [ isNextPageLoading , setNextPageLoading ] = React . useState ( false )
150154 const [ imageViewIndex , setImageViewIndex ] = React . useState ( 0 )
@@ -347,7 +351,10 @@ export const Chat = ({
347351 contentContainerStyle = { [
348352 flatListContentContainer ,
349353 // eslint-disable-next-line react-native/no-inline-styles
350- { justifyContent : chatMessages . length !== 0 ? undefined : 'center' } ,
354+ {
355+ justifyContent : chatMessages . length !== 0 ? undefined : 'center' ,
356+ paddingTop : insets . bottom ,
357+ } ,
351358 ] }
352359 initialNumToRender = { 10 }
353360 ListEmptyComponent = { renderListEmptyComponent }
@@ -376,6 +383,7 @@ export const Chat = ({
376383 flatListProps ,
377384 handleEndReached ,
378385 header ,
386+ insets . bottom ,
379387 keyExtractor ,
380388 renderItem ,
381389 renderListEmptyComponent ,
@@ -387,32 +395,39 @@ export const Chat = ({
387395 < UserContext . Provider value = { user } >
388396 < ThemeContext . Provider value = { theme } >
389397 < L10nContext . Provider value = { { ...l10n [ locale ] , ...l10nOverride } } >
390- < SafeAreaView style = { container } onLayout = { onLayout } >
391- < KeyboardAccessoryView
392- { ... {
393- renderScrollable,
394- style : keyboardAccessoryView ,
395- } }
396- >
397- < Input
398+ < View style = { container } onLayout = { onLayout } >
399+ { customBottomComponent ? (
400+ < >
401+ < > { renderScrollable ( { } ) } </ >
402+ < > { customBottomComponent ( ) } </ >
403+ </ >
404+ ) : (
405+ < KeyboardAccessoryView
398406 { ...{
399- ...unwrap ( inputProps ) ,
400- isAttachmentUploading,
401- onAttachmentPress,
402- onSendPress,
403407 renderScrollable,
404- sendButtonVisibilityMode,
405- textInputProps,
408+ style : keyboardAccessoryView ,
406409 } }
407- />
408- </ KeyboardAccessoryView >
410+ >
411+ < Input
412+ { ...{
413+ ...unwrap ( inputProps ) ,
414+ isAttachmentUploading,
415+ onAttachmentPress,
416+ onSendPress,
417+ renderScrollable,
418+ sendButtonVisibilityMode,
419+ textInputProps,
420+ } }
421+ />
422+ </ KeyboardAccessoryView >
423+ ) }
409424 < ImageView
410425 imageIndex = { imageViewIndex }
411426 images = { gallery }
412427 onRequestClose = { handleRequestClose }
413428 visible = { isImageViewVisible }
414429 />
415- </ SafeAreaView >
430+ </ View >
416431 </ L10nContext . Provider >
417432 </ ThemeContext . Provider >
418433 </ UserContext . Provider >
0 commit comments