All checks were successful
Dev Deploy / Explore-Gitea-Actions (push) Successful in 15s
55 lines
1.8 KiB
TypeScript
55 lines
1.8 KiB
TypeScript
import { Message, Video } from '@/types/ask';
|
|
import { MaterialItem } from '@/types/personal-info';
|
|
import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
import {
|
|
FlatList,
|
|
SafeAreaView
|
|
} from 'react-native';
|
|
import renderMessage from "./aiChat";
|
|
|
|
interface ChatProps {
|
|
userMessages: Message[];
|
|
sessionId: string;
|
|
}
|
|
|
|
function ChatComponent({ userMessages, sessionId }: ChatProps) {
|
|
const flatListRef = useRef<FlatList>(null);
|
|
|
|
const [modalVisible, setModalVisible] = React.useState({ visible: false, data: {} as Video | MaterialItem });
|
|
|
|
// 使用 useCallback 缓存 keyExtractor 函数
|
|
const keyExtractor = useCallback((item: Message) => `${item.role}-${item.timestamp}`, []);
|
|
|
|
// 使用 useMemo 缓存样式对象
|
|
const contentContainerStyle = useMemo(() => ({ padding: 16 }), []);
|
|
|
|
// 自动滚动到底部
|
|
useEffect(() => {
|
|
if (userMessages.length > 0) {
|
|
setTimeout(() => {
|
|
flatListRef.current?.scrollToEnd({ animated: true });
|
|
}, 100);
|
|
}
|
|
}, [userMessages]);
|
|
|
|
return (
|
|
<SafeAreaView className='flex-1'>
|
|
<FlatList
|
|
ref={flatListRef}
|
|
data={userMessages}
|
|
keyExtractor={keyExtractor}
|
|
contentContainerStyle={contentContainerStyle}
|
|
keyboardDismissMode="interactive"
|
|
removeClippedSubviews={true}
|
|
maxToRenderPerBatch={10}
|
|
updateCellsBatchingPeriod={50}
|
|
initialNumToRender={10}
|
|
windowSize={11}
|
|
renderItem={({ item }) => renderMessage({ item, sessionId, modalVisible, setModalVisible })}
|
|
/>
|
|
</SafeAreaView>
|
|
);
|
|
}
|
|
|
|
// 使用 React.memo 包装组件,避免不必要的重渲染
|
|
export default memo(ChatComponent); |