mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-18 19:46:44 +08:00
### What problem does this PR solve? some chunk method pictures are not in English #437 feat: set the height of both html and body to 100% feat: add SharedChat feat: add shared hooks ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -33,9 +33,9 @@
|
||||
.messageEmpty {
|
||||
width: 300px;
|
||||
}
|
||||
.referenceIcon {
|
||||
padding: 0 6px;
|
||||
}
|
||||
// .referenceIcon {
|
||||
// padding: 0 6px;
|
||||
// }
|
||||
}
|
||||
|
||||
.messageItemLeft {
|
||||
@ -46,24 +46,24 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.referencePopoverWrapper {
|
||||
max-width: 50vw;
|
||||
}
|
||||
// .referencePopoverWrapper {
|
||||
// max-width: 50vw;
|
||||
// }
|
||||
|
||||
.referenceChunkImage {
|
||||
width: 10vw;
|
||||
object-fit: contain;
|
||||
}
|
||||
// .referenceChunkImage {
|
||||
// width: 10vw;
|
||||
// object-fit: contain;
|
||||
// }
|
||||
|
||||
.referenceImagePreview {
|
||||
max-width: 45vw;
|
||||
max-height: 45vh;
|
||||
}
|
||||
.chunkContentText {
|
||||
.chunkText;
|
||||
max-height: 45vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.documentLink {
|
||||
padding: 0;
|
||||
}
|
||||
// .referenceImagePreview {
|
||||
// max-width: 45vw;
|
||||
// max-height: 45vh;
|
||||
// }
|
||||
// .chunkContentText {
|
||||
// .chunkText;
|
||||
// max-height: 45vh;
|
||||
// overflow-y: auto;
|
||||
// }
|
||||
// .documentLink {
|
||||
// padding: 0;
|
||||
// }
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { ReactComponent as AssistantIcon } from '@/assets/svg/assistant.svg';
|
||||
import Image from '@/components/image';
|
||||
import NewDocumentLink from '@/components/new-document-link';
|
||||
import DocumentPreviewer from '@/components/pdf-previewer';
|
||||
import { MessageType } from '@/constants/chat';
|
||||
@ -7,7 +6,6 @@ import { useSelectFileThumbnails } from '@/hooks/knowledgeHook';
|
||||
import { useSelectUserInfo } from '@/hooks/userSettingHook';
|
||||
import { IReference, Message } from '@/interfaces/database/chat';
|
||||
import { IChunk } from '@/interfaces/database/knowledge';
|
||||
import { InfoCircleOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
@ -15,18 +13,11 @@ import {
|
||||
Flex,
|
||||
Input,
|
||||
List,
|
||||
Popover,
|
||||
Skeleton,
|
||||
Space,
|
||||
Spin,
|
||||
} from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import Markdown from 'react-markdown';
|
||||
import reactStringReplace from 'react-string-replace';
|
||||
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import { visitParents } from 'unist-util-visit-parents';
|
||||
import { useMemo } from 'react';
|
||||
import {
|
||||
useClickDrawer,
|
||||
useFetchConversationOnMount,
|
||||
@ -35,33 +26,13 @@ import {
|
||||
useSelectConversationLoading,
|
||||
useSendMessage,
|
||||
} from '../hooks';
|
||||
import MarkdownContent from '../markdown-content';
|
||||
|
||||
import SvgIcon from '@/components/svg-icon';
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import { getExtension, isPdf } from '@/utils/documentUtils';
|
||||
import styles from './index.less';
|
||||
|
||||
const reg = /(#{2}\d+\${2})/g;
|
||||
|
||||
const getChunkIndex = (match: string) => Number(match.slice(2, -2));
|
||||
|
||||
const rehypeWrapReference = () => {
|
||||
return function wrapTextTransform(tree: any) {
|
||||
visitParents(tree, 'text', (node, ancestors) => {
|
||||
const latestAncestor = ancestors.at(-1);
|
||||
if (
|
||||
latestAncestor.tagName !== 'custom-typography' &&
|
||||
latestAncestor.tagName !== 'code'
|
||||
) {
|
||||
node.type = 'element';
|
||||
node.tagName = 'custom-typography';
|
||||
node.properties = {};
|
||||
node.children = [{ type: 'text', value: node.value }];
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
const MessageItem = ({
|
||||
item,
|
||||
reference,
|
||||
@ -76,100 +47,6 @@ const MessageItem = ({
|
||||
|
||||
const isAssistant = item.role === MessageType.Assistant;
|
||||
|
||||
const handleDocumentButtonClick = useCallback(
|
||||
(documentId: string, chunk: IChunk, isPdf: boolean) => () => {
|
||||
if (!isPdf) {
|
||||
return;
|
||||
}
|
||||
clickDocumentButton(documentId, chunk);
|
||||
},
|
||||
[clickDocumentButton],
|
||||
);
|
||||
|
||||
const getPopoverContent = useCallback(
|
||||
(chunkIndex: number) => {
|
||||
const chunks = reference?.chunks ?? [];
|
||||
const chunkItem = chunks[chunkIndex];
|
||||
const document = reference?.doc_aggs.find(
|
||||
(x) => x?.doc_id === chunkItem?.doc_id,
|
||||
);
|
||||
const documentId = document?.doc_id;
|
||||
const fileThumbnail = documentId ? fileThumbnails[documentId] : '';
|
||||
const fileExtension = documentId ? getExtension(document?.doc_name) : '';
|
||||
const imageId = chunkItem?.img_id;
|
||||
return (
|
||||
<Flex
|
||||
key={chunkItem?.chunk_id}
|
||||
gap={10}
|
||||
className={styles.referencePopoverWrapper}
|
||||
>
|
||||
{imageId && (
|
||||
<Popover
|
||||
placement="left"
|
||||
content={
|
||||
<Image
|
||||
id={imageId}
|
||||
className={styles.referenceImagePreview}
|
||||
></Image>
|
||||
}
|
||||
>
|
||||
<Image
|
||||
id={imageId}
|
||||
className={styles.referenceChunkImage}
|
||||
></Image>
|
||||
</Popover>
|
||||
)}
|
||||
<Space direction={'vertical'}>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: chunkItem?.content_with_weight,
|
||||
}}
|
||||
className={styles.chunkContentText}
|
||||
></div>
|
||||
{documentId && (
|
||||
<Flex gap={'small'}>
|
||||
{fileThumbnail ? (
|
||||
<img src={fileThumbnail} alt="" />
|
||||
) : (
|
||||
<SvgIcon
|
||||
name={`file-icon/${fileExtension}`}
|
||||
width={24}
|
||||
></SvgIcon>
|
||||
)}
|
||||
<Button
|
||||
type="link"
|
||||
className={styles.documentLink}
|
||||
onClick={handleDocumentButtonClick(
|
||||
documentId,
|
||||
chunkItem,
|
||||
fileExtension === 'pdf',
|
||||
)}
|
||||
>
|
||||
{document?.doc_name}
|
||||
</Button>
|
||||
</Flex>
|
||||
)}
|
||||
</Space>
|
||||
</Flex>
|
||||
);
|
||||
},
|
||||
[reference, fileThumbnails, handleDocumentButtonClick],
|
||||
);
|
||||
|
||||
const renderReference = useCallback(
|
||||
(text: string) => {
|
||||
return reactStringReplace(text, reg, (match, i) => {
|
||||
const chunkIndex = getChunkIndex(match);
|
||||
return (
|
||||
<Popover content={getPopoverContent(chunkIndex)}>
|
||||
<InfoCircleOutlined key={i} className={styles.referenceIcon} />
|
||||
</Popover>
|
||||
);
|
||||
});
|
||||
},
|
||||
[getPopoverContent],
|
||||
);
|
||||
|
||||
const referenceDocumentList = useMemo(() => {
|
||||
return reference?.doc_aggs ?? [];
|
||||
}, [reference?.doc_aggs]);
|
||||
@ -207,38 +84,11 @@ const MessageItem = ({
|
||||
<b>{isAssistant ? '' : userInfo.nickname}</b>
|
||||
<div className={styles.messageText}>
|
||||
{item.content !== '' ? (
|
||||
<Markdown
|
||||
rehypePlugins={[rehypeWrapReference]}
|
||||
remarkPlugins={[remarkGfm]}
|
||||
components={
|
||||
{
|
||||
'custom-typography': ({
|
||||
children,
|
||||
}: {
|
||||
children: string;
|
||||
}) => renderReference(children),
|
||||
code(props: any) {
|
||||
const { children, className, node, ...rest } = props;
|
||||
const match = /language-(\w+)/.exec(className || '');
|
||||
return match ? (
|
||||
<SyntaxHighlighter
|
||||
{...rest}
|
||||
PreTag="div"
|
||||
language={match[1]}
|
||||
>
|
||||
{String(children).replace(/\n$/, '')}
|
||||
</SyntaxHighlighter>
|
||||
) : (
|
||||
<code {...rest} className={className}>
|
||||
{children}
|
||||
</code>
|
||||
);
|
||||
},
|
||||
} as any
|
||||
}
|
||||
>
|
||||
{item.content}
|
||||
</Markdown>
|
||||
<MarkdownContent
|
||||
content={item.content}
|
||||
reference={reference}
|
||||
clickDocumentButton={clickDocumentButton}
|
||||
></MarkdownContent>
|
||||
) : (
|
||||
<Skeleton active className={styles.messageEmpty} />
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user