97 lines
3.8 KiB
TypeScript
97 lines
3.8 KiB
TypeScript
import { ContentPart, Message } from '@/types/ask';
|
|
import React, { Dispatch, ForwardedRef, forwardRef, SetStateAction, useCallback, useMemo, 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<FlatListProps<Message>, 'data' | 'renderItem'> {
|
|
userMessages: Message[];
|
|
sessionId: string;
|
|
setSelectedImages: Dispatch<SetStateAction<string[]>>;
|
|
selectedImages: string[];
|
|
}
|
|
|
|
function ChatComponent(
|
|
{ userMessages, sessionId, setSelectedImages, selectedImages, ...restProps }: ChatProps,
|
|
ref: ForwardedRef<FlatList<Message>>
|
|
) {
|
|
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 renderMessageItem = useCallback(({ item, index }: { item: Message, index: number }) => {
|
|
const itemStyle = index === 0 ? { marginTop: 16, marginHorizontal: 16 } : { marginHorizontal: 16 };
|
|
return (
|
|
<View style={itemStyle}>
|
|
<MessageItem
|
|
item={item}
|
|
insets={insets}
|
|
sessionId={sessionId}
|
|
modalVisible={modalVisible}
|
|
setModalVisible={setModalVisible}
|
|
modalDetailsVisible={modalDetailsVisible}
|
|
setModalDetailsVisible={setModalDetailsVisible}
|
|
selectedImages={selectedImages}
|
|
setSelectedImages={setSelectedImages}
|
|
t={t}
|
|
cancel={cancel}
|
|
setCancel={setCancel}
|
|
/>
|
|
</View>
|
|
);
|
|
}, [insets, sessionId, modalVisible, modalDetailsVisible, selectedImages, t, cancel]);
|
|
|
|
return (
|
|
<SafeAreaView style={{ flex: 1 }}>
|
|
<FlatList
|
|
ref={ref}
|
|
data={userMessages}
|
|
keyExtractor={keyExtractor}
|
|
renderItem={renderMessageItem}
|
|
contentContainerStyle={contentContainerStyle}
|
|
keyboardDismissMode="interactive"
|
|
keyboardShouldPersistTaps="handled"
|
|
removeClippedSubviews={true}
|
|
maxToRenderPerBatch={10}
|
|
updateCellsBatchingPeriod={50}
|
|
initialNumToRender={10}
|
|
windowSize={11}
|
|
{...restProps} // 将所有其他属性传递给 FlatList
|
|
/>
|
|
{/* 单个图片弹窗 */}
|
|
<SingleContentModel modalVisible={modalVisible} setModalVisible={setModalVisible} />
|
|
{/* 全部图片详情弹窗 */}
|
|
<SelectModel
|
|
modalDetailsVisible={modalDetailsVisible}
|
|
setModalDetailsVisible={setModalDetailsVisible}
|
|
insets={insets}
|
|
setSelectedImages={setSelectedImages}
|
|
selectedImages={selectedImages}
|
|
t={t}
|
|
setCancel={setCancel}
|
|
cancel={cancel}
|
|
/>
|
|
</SafeAreaView>
|
|
);
|
|
}
|
|
|
|
export default React.memo(forwardRef(ChatComponent)); |