Skip to content

Commit

Permalink
fix: replace some pictures of chunk method infiniflow#437 (infiniflow…
Browse files Browse the repository at this point in the history
…#438)

### What problem does this PR solve?

some chunk method pictures are not in English infiniflow#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)
  • Loading branch information
cike8899 authored Apr 18, 2024
1 parent 880c022 commit 309c4e2
Show file tree
Hide file tree
Showing 26 changed files with 1,336 additions and 733 deletions.
116 changes: 57 additions & 59 deletions web/src/assets/svg/chunk-method/law-02.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
131 changes: 73 additions & 58 deletions web/src/assets/svg/chunk-method/manual-02.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
115 changes: 57 additions & 58 deletions web/src/assets/svg/chunk-method/manual-04.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
173 changes: 97 additions & 76 deletions web/src/assets/svg/chunk-method/qa-01.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
118 changes: 59 additions & 59 deletions web/src/assets/svg/chunk-method/qa-02.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
117 changes: 58 additions & 59 deletions web/src/assets/svg/chunk-method/resume-02.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
108 changes: 60 additions & 48 deletions web/src/assets/svg/chunk-method/table-01.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
172 changes: 57 additions & 115 deletions web/src/assets/svg/chunk-method/table-02.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions web/src/global.less
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
@import url(./inter.less);

html {
height: 100%;
}

body {
font-family: Inter;
margin: 0;
height: 100%;
}

#root {
height: 100%;
}

.ant-app {
height: 100%;
}
77 changes: 76 additions & 1 deletion web/src/hooks/chatHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
IStats,
IToken,
} from '@/interfaces/database/chat';
import { useCallback } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'umi';

export const useFetchDialogList = () => {
Expand Down Expand Up @@ -248,3 +248,78 @@ export const useSelectStats = () => {
};

//#endregion

//#region shared chat

export const useCreateSharedConversation = () => {
const dispatch = useDispatch();

const createSharedConversation = useCallback(
(userId?: string) => {
return dispatch<any>({
type: 'chatModel/createExternalConversation',
payload: { userId },
});
},
[dispatch],
);

return createSharedConversation;
};

export const useFetchSharedConversation = () => {
const dispatch = useDispatch();

const fetchSharedConversation = useCallback(
(conversationId: string) => {
return dispatch<any>({
type: 'chatModel/getExternalConversation',
payload: conversationId,
});
},
[dispatch],
);

return fetchSharedConversation;
};

export const useCompleteSharedConversation = () => {
const dispatch = useDispatch();

const completeSharedConversation = useCallback(
(payload: any) => {
return dispatch<any>({
type: 'chatModel/completeExternalConversation',
payload: payload,
});
},
[dispatch],
);

return completeSharedConversation;
};

export const useCreatePublicUrlToken = (dialogId: string, visible: boolean) => {
const [token, setToken] = useState();
const createToken = useCreateToken(dialogId);
const { protocol, host } = window.location;

const urlWithToken = `${protocol}//${host}/chat/share?shared_id=${token}`;

const createUrlToken = useCallback(async () => {
if (visible) {
const data = await createToken();
const urlToken = data.data?.token;
if (urlToken) {
setToken(urlToken);
}
}
}, [createToken, visible]);

useEffect(() => {
createUrlToken();
}, [createUrlToken]);

return { token, createUrlToken, urlWithToken };
};
//#endregion
44 changes: 22 additions & 22 deletions web/src/pages/chat/chat-container/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
.messageEmpty {
width: 300px;
}
.referenceIcon {
padding: 0 6px;
}
// .referenceIcon {
// padding: 0 6px;
// }
}

.messageItemLeft {
Expand All @@ -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;
// }
164 changes: 7 additions & 157 deletions web/src/pages/chat/chat-container/index.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,23 @@
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';
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,
Drawer,
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,
Expand All @@ -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,
Expand All @@ -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]);
Expand Down Expand Up @@ -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} />
)}
Expand Down
Loading

0 comments on commit 309c4e2

Please sign in to comment.