import { ContentPart, Message } from '@/types/ask'; import React, { Dispatch, ForwardedRef, forwardRef, SetStateAction, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { FlatList, FlatListProps, SafeAreaView, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import MessageItem from '../chat/message-item/message-item'; import SelectModel from "./selectModel"; import SingleContentModel from "./singleContentModel"; // 继承 FlatListProps 来接收所有 FlatList 的属性 interface ChatProps extends Omit, 'data' | 'renderItem'> { userMessages: Message[]; sessionId: string; setSelectedImages: Dispatch>; selectedImages: string[]; } function ChatComponent( { userMessages, sessionId, setSelectedImages, selectedImages, ...restProps }: ChatProps, ref: ForwardedRef> ) { const insets = useSafeAreaInsets(); const [modalVisible, setModalVisible] = React.useState({ visible: false, data: {} as ContentPart }); const { t } = useTranslation(); const keyExtractor = useCallback((item: Message) => `${item.role}-${item.timestamp}`, []); // 取消展示右键菜单 const [cancel, setCancel] = useState(true); const contentContainerStyle = useMemo(() => ({ padding: 16, flexGrow: 1, paddingTop: 0, }), []); const [modalDetailsVisible, setModalDetailsVisible] = useState<{ visible: boolean, content: any }>({ visible: false, content: [] }); const flatListRef = useRef(null); const prevMessagesLength = useRef(0); // 自动滚动到底部 useEffect(() => { if (userMessages.length > 0 && userMessages.length !== prevMessagesLength.current) { setTimeout(() => { flatListRef.current?.scrollToEnd({ animated: true }); }, 100); prevMessagesLength.current = userMessages.length; } }, [userMessages.length]); const renderMessageItem = useCallback(({ item, index }: { item: Message, index: number }) => { const itemStyle = index === 0 ? { marginTop: 16, marginHorizontal: 16 } : { marginHorizontal: 16 }; return ( ); }, [insets, sessionId, modalVisible, modalDetailsVisible, selectedImages, t, cancel]); return ( { // 处理转发 ref 和内部 ref if (ref) { if (typeof ref === 'function') { ref(node); } else { ref.current = node; } } flatListRef.current = node; }} data={userMessages} keyExtractor={keyExtractor} renderItem={renderMessageItem} contentContainerStyle={contentContainerStyle} keyboardDismissMode="interactive" keyboardShouldPersistTaps="handled" removeClippedSubviews={true} maxToRenderPerBatch={10} updateCellsBatchingPeriod={50} initialNumToRender={10} windowSize={11} onContentSizeChange={() => { if (userMessages.length > 0) { flatListRef.current?.scrollToEnd({ animated: true }); } }} onLayout={() => { if (userMessages.length > 0) { flatListRef.current?.scrollToEnd({ animated: false }); } }} {...restProps} /> {/* 单个图片弹窗 */} {/* 全部图片详情弹窗 */} ); } export default React.memo(forwardRef(ChatComponent));