161 lines
5.0 KiB
TypeScript
161 lines
5.0 KiB
TypeScript
import MoreSvg from "@/assets/icons/svg/more.svg";
|
|
import { ContentPart, getMessageText, isMessageContainMedia } from "@/types/ask";
|
|
import { TFunction } from 'i18next';
|
|
import React from 'react';
|
|
import { Platform, StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
import Markdown from "react-native-markdown-display";
|
|
import Loading from '../../ask/threeCircle';
|
|
import { ThemedText } from "../../ThemedText";
|
|
import MediaGrid from './MediaGrid';
|
|
|
|
interface MessageContentProps {
|
|
item: any;
|
|
isUser: boolean;
|
|
setModalVisible: React.Dispatch<React.SetStateAction<{ visible: boolean, data: ContentPart }>>;
|
|
setCancel: React.Dispatch<React.SetStateAction<boolean>>;
|
|
cancel: boolean;
|
|
t: TFunction;
|
|
setSelectedImages: React.Dispatch<React.SetStateAction<string[]>>;
|
|
setModalDetailsVisible: React.Dispatch<React.SetStateAction<{ visible: boolean, content: any }>>;
|
|
}
|
|
|
|
const chineseMarkdownStyle = StyleSheet.create({
|
|
// General body text
|
|
body: {
|
|
fontSize: 14,
|
|
lineHeight: 24.5, // 1.75 * fontSize for better readability
|
|
color: '#333',
|
|
},
|
|
// Headings
|
|
heading1: {
|
|
fontSize: 24,
|
|
fontWeight: 'bold',
|
|
marginTop: 10,
|
|
marginBottom: 10,
|
|
lineHeight: 36,
|
|
borderBottomWidth: 1,
|
|
borderColor: '#eee',
|
|
paddingBottom: 5,
|
|
},
|
|
heading2: {
|
|
fontSize: 22,
|
|
fontWeight: 'bold',
|
|
marginTop: 8,
|
|
marginBottom: 8,
|
|
lineHeight: 33,
|
|
},
|
|
heading3: {
|
|
fontSize: 20,
|
|
fontWeight: 'bold',
|
|
marginTop: 6,
|
|
marginBottom: 6,
|
|
lineHeight: 30,
|
|
},
|
|
// Paragraph: Add vertical margin for better separation
|
|
paragraph: {
|
|
marginTop: 10,
|
|
marginBottom: 10,
|
|
},
|
|
// Lists
|
|
bullet_list_icon: {
|
|
fontSize: 16,
|
|
lineHeight: 28,
|
|
marginRight: 8,
|
|
},
|
|
list_item: {
|
|
flexDirection: 'row',
|
|
alignItems: 'flex-start',
|
|
marginBottom: 8,
|
|
},
|
|
// Code blocks
|
|
code_block: {
|
|
fontFamily: Platform.OS === 'ios' ? 'Courier New' : 'monospace',
|
|
backgroundColor: '#f5f5f5',
|
|
padding: 15,
|
|
borderRadius: 4,
|
|
marginVertical: 10,
|
|
fontSize: 14,
|
|
lineHeight: 21,
|
|
},
|
|
// Blockquote
|
|
blockquote: {
|
|
backgroundColor: '#f0f0f0',
|
|
borderLeftColor: '#ccc',
|
|
borderLeftWidth: 4,
|
|
paddingHorizontal: 15,
|
|
paddingVertical: 10,
|
|
marginVertical: 10,
|
|
},
|
|
// Link
|
|
link: {
|
|
color: '#007aff', // Standard blue link color
|
|
textDecorationLine: 'underline',
|
|
},
|
|
// Horizontal Rule
|
|
hr: {
|
|
backgroundColor: '#e0e0e0',
|
|
height: 1,
|
|
marginVertical: 15,
|
|
},
|
|
});
|
|
|
|
const MessageContent = ({
|
|
item,
|
|
isUser,
|
|
setModalVisible,
|
|
setCancel,
|
|
cancel,
|
|
t,
|
|
setSelectedImages,
|
|
setModalDetailsVisible
|
|
}: MessageContentProps) => {
|
|
return (
|
|
<View className={`${isUser ? 'bg-bgPrimary' : 'bg-aiBubble'} rounded-2xl`}>
|
|
{getMessageText(item) == "keepSearchIng" && !isUser ? (
|
|
<Loading />
|
|
) : (
|
|
<View className="px-2">
|
|
<Markdown style={chineseMarkdownStyle}>
|
|
{getMessageText(item)}
|
|
</Markdown>
|
|
</View>
|
|
)}
|
|
|
|
|
|
{isMessageContainMedia(item) && (
|
|
<View className="relative">
|
|
{item.content instanceof Array && (() => {
|
|
const mediaItems = item.content.filter((media: ContentPart) => media.type !== 'text');
|
|
|
|
return (
|
|
<View className="mt-2">
|
|
<MediaGrid
|
|
mediaItems={mediaItems}
|
|
setModalVisible={setModalVisible}
|
|
setCancel={setCancel}
|
|
cancel={cancel}
|
|
t={t}
|
|
/>
|
|
</View>
|
|
);
|
|
})()}
|
|
{
|
|
(item.content instanceof Array && item.content.length > 3)
|
|
&& <TouchableOpacity className="absolute top-1/2 -translate-y-1/2 -right-4 translate-x-1/2 bg-bgPrimary flex flex-row items-center gap-2 p-1 pl-2 rounded-full" onPress={() => {
|
|
setSelectedImages([])
|
|
setModalDetailsVisible({ visible: true, content: item.content });
|
|
}}>
|
|
<ThemedText className="!text-white font-semibold">{item.content.length}</ThemedText>
|
|
<View className="bg-white rounded-full p-2">
|
|
<MoreSvg />
|
|
</View>
|
|
</TouchableOpacity>
|
|
}
|
|
</View>
|
|
)}
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default React.memo(MessageContent);
|