import * as React from 'react'; import { Animated, ListRenderItemInfo, View } from 'react-native'; import { ChatConversationType } from '../../rename.chat'; import { Alert } from '../../ui/Alert'; import { FlatListFactory } from '../../ui/FlatList'; import { BottomSheetEmojiList } from '../BottomSheetEmojiList/BottomSheetEmojiList'; import { BottomSheetReactionDetail } from '../BottomSheetReactionDetail'; import { BottomSheetMessageReport } from '../MessageReport'; import { EmptyPlaceholder, ErrorPlaceholder, LoadingPlaceholder, } from '../Placeholder'; import { useMessageList } from './MessageList.hooks'; import { AnimatedMessagePin, AnimatedMessagePinPlaceholder, } from './MessagePin'; import { useMessagePin } from './MessagePin.hooks'; import type { MessageListItemProps, MessageListProps, MessageListRef, } from './types'; /** * Message List Component. * * This component can display sent and received messages, display historical messages, play language messages, preview pictures, video messages, download files, and customize behaviors and styles such as previewing pictures, previewing videos, and downloading documents. Custom messages can be added and more. Usually used in conjunction with the `MessageInput` component. */ export const MessageList = React.forwardRef( function (props: MessageListProps, ref?: React.ForwardedRef) { const FlatList = React.useMemo( () => FlatListFactory(), [] ); const { containerStyle, convId, convType, onChangePinMaskHeight, type: comType, onRequestClosePinMessage, } = props; const { ref: flatListRef, data, onInit, viewabilityConfig, onViewableItemsChanged, listState, menuRef, alertRef, onRequestCloseMenu, onClickedItem, onLongPressItem, inverted, reachedThreshold, reportRef, reportMessage, reportData, onClickedItemAvatar, onClickedItemQuote, onClickedItemState, ListItemRender, listItemRenderProps, scrollEventThrottle, onMomentumScrollEnd, onScroll, onTouchMove, onScrollBeginDrag, onScrollEndDrag, onLayout, bounces, onContentSizeChange, onRenderItem, emojiRef, emojiList, onRequestCloseEmoji, onClickedItemReaction, onClickedFaceListItem, reactionRef, onRequestCloseReaction, onClickedItemThread, onCheckedItem, onLongPressItemReaction, pinMsgListRef, onContainerLayout, maxListHeightRef, enableMessagePin, MessageLongPressMenu, onClickMessageList, } = useMessageList(props, ref); const { msgPinPlaceHolderCurrentHeight, msgPinPlaceHolderHeightAnimate, msgListMaxCurrentHeight, msgPinCurrentHeight, msgPinHeightRef, msgPinHeightAnimate, panHandlers, setMaxListHeight, msgPinLabelTranslateYRef, msgPinLabelTranslateYAnimate, msgPinLabelCurrentTranslateY, msgPinBackgroundCurrentOpacity, msgPinBackgroundOpacityAnimate, } = useMessagePin({}); // const { getColor } = useColors(); return ( { maxListHeightRef.current = e.nativeEvent.layout.height; setMaxListHeight(e.nativeEvent.layout.height); }} > {/* {backgroundImageComponent ? ( backgroundImageComponent ) : backgroundImage ? ( ) : null} */} {(convType === ChatConversationType.GroupChat || convType === ChatConversationType.PeerChat) && comType === 'chat' ? ( ) : null} // ) : undefined // } // style={{ flexGrow: 1 }} // contentContainerStyle={{ flexGrow: 1 }} data={data} // refreshing={refreshing} // onRefresh={onRefresh} inverted={inverted} scrollEventThrottle={scrollEventThrottle} renderItem={(info: ListRenderItemInfo) => { const { item, index } = info; onRenderItem(info); return ( ); }} keyExtractor={(item: MessageListItemProps) => { return item.id; }} // onEndReached={onMore} onEndReachedThreshold={reachedThreshold} viewabilityConfig={viewabilityConfig} onViewableItemsChanged={onViewableItemsChanged} onMomentumScrollEnd={onMomentumScrollEnd} onScroll={onScroll} onScrollEndDrag={onScrollEndDrag} onScrollBeginDrag={onScrollBeginDrag} bounces={bounces} onTouchMove={onTouchMove} maintainVisibleContentPosition={{ // !!! This effect does not work well when inserting the first element without scrolling. minIndexForVisible: 0, // autoscrollToTopThreshold: -(Dimensions.get('window').height * 2), }} // !!! https://github.com/facebook/react-native/issues/42967 // !!! https://github.com/facebook/react-native/issues/36766 // !!! https://github.com/facebook/react-native/issues/39421 // initialNumToRender={9999} // renderScrollComponent={null} // maxToRenderPerBatch={50} // overScrollMode={'always'} // !!! This effect does not work well when inserting the first element without scrolling. // maintainVisibleContentPosition={{ // minIndexForVisible: 0, // autoscrollToTopThreshold: 10, // }} // ListEmptyComponent={EmptyPlaceholder} // ListErrorComponent={ // listState === 'error' ? ( // { // onInit?.(); // }} // /> // ) : null // } // ListLoadingComponent={ // listState === 'loading' ? : null // } /> {enableMessagePin === true && (convType === ChatConversationType.GroupChat || convType === ChatConversationType.PeerChat) && comType === 'chat' ? ( ) : null} {listState === 'empty' ? : null} {listState === 'loading' ? : null} {listState === 'error' ? ( { onInit?.(); }} /> ) : null} {MessageLongPressMenu ? ( ) : null} ); } ); export const MessageListMemo = React.memo(MessageList);