mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-06-04 11:24:00 +08:00

* fix: by obtaining the width and height of the pdf and passing it to boundingRect, the problem of inaccurate positioning of file highlighting is fixed * feat: remove actualPositions from buildChunkHighlights
130 lines
3.4 KiB
TypeScript
130 lines
3.4 KiB
TypeScript
import {
|
|
useGetChunkHighlights,
|
|
useGetDocumentUrl,
|
|
} from '@/hooks/documentHooks';
|
|
import { IChunk } from '@/interfaces/database/knowledge';
|
|
import { Skeleton } from 'antd';
|
|
import { useEffect, useRef, useState } from 'react';
|
|
import {
|
|
AreaHighlight,
|
|
Highlight,
|
|
IHighlight,
|
|
PdfHighlighter,
|
|
PdfLoader,
|
|
Popup,
|
|
} from 'react-pdf-highlighter';
|
|
|
|
import styles from './index.less';
|
|
|
|
interface IProps {
|
|
chunk: IChunk;
|
|
documentId: string;
|
|
visible: boolean;
|
|
}
|
|
|
|
const HighlightPopup = ({
|
|
comment,
|
|
}: {
|
|
comment: { text: string; emoji: string };
|
|
}) =>
|
|
comment.text ? (
|
|
<div className="Highlight__popup">
|
|
{comment.emoji} {comment.text}
|
|
</div>
|
|
) : null;
|
|
|
|
const DocumentPreviewer = ({ chunk, documentId, visible }: IProps) => {
|
|
const url = useGetDocumentUrl(documentId);
|
|
const { highlights: state, setWidthAndHeight } = useGetChunkHighlights(chunk);
|
|
const ref = useRef<(highlight: IHighlight) => void>(() => {});
|
|
const [loaded, setLoaded] = useState(false);
|
|
|
|
const resetHash = () => {};
|
|
|
|
useEffect(() => {
|
|
setLoaded(visible);
|
|
}, [visible]);
|
|
|
|
useEffect(() => {
|
|
if (state.length > 0 && loaded) {
|
|
setLoaded(false);
|
|
ref.current(state[0]);
|
|
}
|
|
}, [state, loaded]);
|
|
|
|
return (
|
|
<div className={styles.documentContainer}>
|
|
<PdfLoader
|
|
url={url}
|
|
beforeLoad={<Skeleton active />}
|
|
workerSrc="/pdfjs-dist/pdf.worker.min.js"
|
|
>
|
|
{(pdfDocument) => {
|
|
pdfDocument.getPage(1).then((page) => {
|
|
const viewport = page.getViewport({ scale: 1 });
|
|
const width = viewport.width;
|
|
const height = viewport.height;
|
|
setWidthAndHeight(width, height);
|
|
});
|
|
|
|
return (
|
|
<PdfHighlighter
|
|
pdfDocument={pdfDocument}
|
|
enableAreaSelection={(event) => event.altKey}
|
|
onScrollChange={resetHash}
|
|
scrollRef={(scrollTo) => {
|
|
ref.current = scrollTo;
|
|
setLoaded(true);
|
|
}}
|
|
onSelectionFinished={() => null}
|
|
highlightTransform={(
|
|
highlight,
|
|
index,
|
|
setTip,
|
|
hideTip,
|
|
viewportToScaled,
|
|
screenshot,
|
|
isScrolledTo,
|
|
) => {
|
|
const isTextHighlight = !Boolean(
|
|
highlight.content && highlight.content.image,
|
|
);
|
|
|
|
const component = isTextHighlight ? (
|
|
<Highlight
|
|
isScrolledTo={isScrolledTo}
|
|
position={highlight.position}
|
|
comment={highlight.comment}
|
|
/>
|
|
) : (
|
|
<AreaHighlight
|
|
isScrolledTo={isScrolledTo}
|
|
highlight={highlight}
|
|
onChange={() => {}}
|
|
/>
|
|
);
|
|
|
|
return (
|
|
<Popup
|
|
popupContent={<HighlightPopup {...highlight} />}
|
|
onMouseOver={(popupContent) =>
|
|
setTip(highlight, () => popupContent)
|
|
}
|
|
onMouseOut={hideTip}
|
|
key={index}
|
|
>
|
|
{component}
|
|
</Popup>
|
|
);
|
|
}}
|
|
highlights={state}
|
|
/>
|
|
);
|
|
}}
|
|
</PdfLoader>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default DocumentPreviewer;
|