diff --git a/src/components/Chat/Chat.tsx b/src/components/Chat/Chat.tsx index 27411ef..520d86d 100644 --- a/src/components/Chat/Chat.tsx +++ b/src/components/Chat/Chat.tsx @@ -12,13 +12,13 @@ import { GestureResponderHandlers, InteractionManager, LayoutAnimation, - SafeAreaView, StatusBar, StatusBarProps, Text, View, } from 'react-native' import ImageView from 'react-native-image-viewing' +import { useSafeAreaInsets } from 'react-native-safe-area-context' import { usePrevious } from '../../hooks' import { l10n } from '../../l10n' @@ -48,6 +48,8 @@ dayjs.extend(calendar) export type ChatTopLevelProps = InputTopLevelProps & MessageTopLevelProps export interface ChatProps extends ChatTopLevelProps { + /** Allows you to replace the default Input widget e.g. if you want to create a channel view. */ + customBottomComponent?: () => React.ReactNode /** If {@link ChatProps.dateFormat} and/or {@link ChatProps.timeFormat} is not enough to * customize date headers in your case, use this to return an arbitrary * string based on a `dateTime` of a particular message. Can be helpful to @@ -99,6 +101,7 @@ export interface ChatProps extends ChatTopLevelProps { /** Entry component, represents the complete chat */ export const Chat = ({ + customBottomComponent, customDateHeaderText, dateFormat, disableImageGallery, @@ -145,6 +148,7 @@ export const Chat = ({ const { onLayout, size } = useComponentSize() const animationRef = React.useRef(false) const list = React.useRef>(null) + const insets = useSafeAreaInsets() const [isImageViewVisible, setIsImageViewVisible] = React.useState(false) const [isNextPageLoading, setNextPageLoading] = React.useState(false) const [imageViewIndex, setImageViewIndex] = React.useState(0) @@ -347,7 +351,10 @@ export const Chat = ({ contentContainerStyle={[ flatListContentContainer, // eslint-disable-next-line react-native/no-inline-styles - { justifyContent: chatMessages.length !== 0 ? undefined : 'center' }, + { + justifyContent: chatMessages.length !== 0 ? undefined : 'center', + paddingTop: insets.bottom, + }, ]} initialNumToRender={10} ListEmptyComponent={renderListEmptyComponent} @@ -376,6 +383,7 @@ export const Chat = ({ flatListProps, handleEndReached, header, + insets.bottom, keyExtractor, renderItem, renderListEmptyComponent, @@ -387,32 +395,39 @@ export const Chat = ({ - - - + {customBottomComponent ? ( + <> + <>{renderScrollable({})} + <>{customBottomComponent()} + + ) : ( + - + > + + + )} - + diff --git a/src/components/Chat/__tests__/Chat.test.tsx b/src/components/Chat/__tests__/Chat.test.tsx index 6787ea1..18a4b12 100644 --- a/src/components/Chat/__tests__/Chat.test.tsx +++ b/src/components/Chat/__tests__/Chat.test.tsx @@ -1,5 +1,6 @@ import { fireEvent, render } from '@testing-library/react-native' import * as React from 'react' +import { Text } from 'react-native' import { fileMessage, @@ -165,4 +166,26 @@ describe('chat', () => { const placeholder = getByText(l10n.en.emptyChatPlaceholder) expect(placeholder).toBeDefined() }) + + it('renders custom bottom component', () => { + expect.assertions(1) + const customBottomComponent = jest.fn(() => Bottom) + const messages = [] + const onSendPress = jest.fn() + const onMessagePress = jest.fn() + const { getByText } = render( + + ) + + const customComponent = getByText('Bottom') + expect(customComponent).toBeDefined() + }) })