diff --git a/web/src/components/pdf-previewer/index.tsx b/web/src/components/pdf-previewer/index.tsx index a9b64a6c2b6cf0cf511b5210e3f24541accb98f2..b101eda44cc1ed0f85823215e107c7a5d3ebdbea 100644 --- a/web/src/components/pdf-previewer/index.tsx +++ b/web/src/components/pdf-previewer/index.tsx @@ -35,7 +35,7 @@ const HighlightPopup = ({ const DocumentPreviewer = ({ chunk, documentId, visible }: IProps) => { const url = useGetDocumentUrl(documentId); - const state = useGetChunkHighlights(chunk); + const { highlights: state, setWidthAndHeight } = useGetChunkHighlights(chunk); const ref = useRef<(highlight: IHighlight) => void>(() => {}); const [loaded, setLoaded] = useState(false); @@ -59,59 +59,68 @@ const DocumentPreviewer = ({ chunk, documentId, visible }: IProps) => { beforeLoad={<Skeleton active />} workerSrc="/pdfjs-dist/pdf.worker.min.js" > - {(pdfDocument) => ( - <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, - ); + {(pdfDocument) => { + pdfDocument.getPage(1).then((page) => { + const viewport = page.getViewport({ scale: 1 }); + const width = viewport.width; + const height = viewport.height; + setWidthAndHeight(width, height); + }); - const component = isTextHighlight ? ( - <Highlight - isScrolledTo={isScrolledTo} - position={highlight.position} - comment={highlight.comment} - /> - ) : ( - <AreaHighlight - isScrolledTo={isScrolledTo} - highlight={highlight} - onChange={() => {}} - /> - ); + 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, + ); - return ( - <Popup - popupContent={<HighlightPopup {...highlight} />} - onMouseOver={(popupContent) => - setTip(highlight, () => popupContent) - } - onMouseOut={hideTip} - key={index} - > - {component} - </Popup> - ); - }} - highlights={state} - /> - )} + 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> ); diff --git a/web/src/hooks/documentHooks.ts b/web/src/hooks/documentHooks.ts index f3b75bf7780fd7b6ae4c8054f1c8449b032e616d..19dae5c72a99771606db4a1ea09d619bbea43933 100644 --- a/web/src/hooks/documentHooks.ts +++ b/web/src/hooks/documentHooks.ts @@ -2,7 +2,7 @@ import { IChunk, IKnowledgeFile } from '@/interfaces/database/knowledge'; import { IChangeParserConfigRequestBody } from '@/interfaces/request/document'; import { api_host } from '@/utils/api'; import { buildChunkHighlights } from '@/utils/documentUtils'; -import { useCallback, useMemo } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import { IHighlight } from 'react-pdf-highlighter'; import { useDispatch, useSelector } from 'umi'; import { useGetKnowledgeSearchParams } from './routeHook'; @@ -15,12 +15,23 @@ export const useGetDocumentUrl = (documentId: string) => { return url; }; -export const useGetChunkHighlights = (selectedChunk: IChunk): IHighlight[] => { +export const useGetChunkHighlights = (selectedChunk: IChunk) => { + const [size, setSize] = useState({ width: 849, height: 1200 }); + const highlights: IHighlight[] = useMemo(() => { - return buildChunkHighlights(selectedChunk); - }, [selectedChunk]); + return buildChunkHighlights(selectedChunk, size); + }, [selectedChunk, size]); + + const setWidthAndHeight = (width: number, height: number) => { + setSize((pre) => { + if (pre.height !== height || pre.width !== width) { + return { height, width }; + } + return pre; + }); + }; - return highlights; + return { highlights, setWidthAndHeight }; }; export const useFetchDocumentList = () => { diff --git a/web/src/less/mixins.less b/web/src/less/mixins.less index 85c808a312d2239e6041b94a949e41cc7e6e9442..b5256f7e0f8ccd36e831a5d89b1c7d6eeb1e02c8 100644 --- a/web/src/less/mixins.less +++ b/web/src/less/mixins.less @@ -9,11 +9,11 @@ caption { color: @blurBackground; - font-size: 20px; - height: 50px; - line-height: 50px; + font-size: 14px; + height: 20px; + line-height: 20px; font-weight: 600; - margin-bottom: 10px; + margin-bottom: 6px; } th { diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/preview.tsx b/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/preview.tsx index 6ec4f6568a2e5c18e797d5f07ad1f88a7625ec99..f228e8e23a4f7730270f265638e2a12e5d7a18ba 100644 --- a/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/preview.tsx +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/preview.tsx @@ -30,7 +30,8 @@ const HighlightPopup = ({ // TODO: merge with DocumentPreviewer const Preview = ({ selectedChunkId }: IProps) => { const url = useGetDocumentUrl(); - const state = useGetChunkHighlights(selectedChunkId); + const { highlights: state, setWidthAndHeight } = + useGetChunkHighlights(selectedChunkId); const ref = useRef<(highlight: IHighlight) => void>(() => {}); const resetHash = () => {}; @@ -48,58 +49,67 @@ const Preview = ({ selectedChunkId }: IProps) => { beforeLoad={<Skeleton active />} workerSrc="/pdfjs-dist/pdf.worker.min.js" > - {(pdfDocument) => ( - <PdfHighlighter - pdfDocument={pdfDocument} - enableAreaSelection={(event) => event.altKey} - onScrollChange={resetHash} - scrollRef={(scrollTo) => { - ref.current = scrollTo; - }} - onSelectionFinished={() => null} - highlightTransform={( - highlight, - index, - setTip, - hideTip, - viewportToScaled, - screenshot, - isScrolledTo, - ) => { - const isTextHighlight = !Boolean( - highlight.content && highlight.content.image, - ); + {(pdfDocument) => { + pdfDocument.getPage(1).then((page) => { + const viewport = page.getViewport({ scale: 1 }); + const width = viewport.width; + const height = viewport.height; + setWidthAndHeight(width, height); + }); - const component = isTextHighlight ? ( - <Highlight - isScrolledTo={isScrolledTo} - position={highlight.position} - comment={highlight.comment} - /> - ) : ( - <AreaHighlight - isScrolledTo={isScrolledTo} - highlight={highlight} - onChange={() => {}} - /> - ); + return ( + <PdfHighlighter + pdfDocument={pdfDocument} + enableAreaSelection={(event) => event.altKey} + onScrollChange={resetHash} + scrollRef={(scrollTo) => { + ref.current = scrollTo; + }} + onSelectionFinished={() => null} + highlightTransform={( + highlight, + index, + setTip, + hideTip, + viewportToScaled, + screenshot, + isScrolledTo, + ) => { + const isTextHighlight = !Boolean( + highlight.content && highlight.content.image, + ); - return ( - <Popup - popupContent={<HighlightPopup {...highlight} />} - onMouseOver={(popupContent) => - setTip(highlight, () => popupContent) - } - onMouseOut={hideTip} - key={index} - > - {component} - </Popup> - ); - }} - highlights={state} - /> - )} + 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> ); diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/hooks.ts b/web/src/pages/add-knowledge/components/knowledge-chunk/hooks.ts index 59bf2fd24875c77b29629ec03ae8f1b7980e88e4..724f14e3026017b3cdf42cbe03e6fed2e864c314 100644 --- a/web/src/pages/add-knowledge/components/knowledge-chunk/hooks.ts +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/hooks.ts @@ -36,16 +36,24 @@ export const useGetSelectedChunk = (selectedChunkId: string) => { ); }; -export const useGetChunkHighlights = ( - selectedChunkId: string, -): IHighlight[] => { +export const useGetChunkHighlights = (selectedChunkId: string) => { + const [size, setSize] = useState({ width: 849, height: 1200 }); const selectedChunk: IChunk = useGetSelectedChunk(selectedChunkId); const highlights: IHighlight[] = useMemo(() => { - return buildChunkHighlights(selectedChunk); - }, [selectedChunk]); + return buildChunkHighlights(selectedChunk, size); + }, [selectedChunk, size]); - return highlights; + const setWidthAndHeight = (width: number, height: number) => { + setSize((pre) => { + if (pre.height !== height || pre.width !== width) { + return { height, width }; + } + return pre; + }); + }; + + return { highlights, setWidthAndHeight }; }; export const useSelectChunkListLoading = () => { diff --git a/web/src/utils/documentUtils.ts b/web/src/utils/documentUtils.ts index 4119fa956102cc94929f448df39c0a0a20d769dd..45e8968eafb60dc82b633539016902c8823592a0 100644 --- a/web/src/utils/documentUtils.ts +++ b/web/src/utils/documentUtils.ts @@ -2,20 +2,20 @@ import { IChunk } from '@/interfaces/database/knowledge'; import { UploadFile } from 'antd'; import { v4 as uuid } from 'uuid'; -export const buildChunkHighlights = (selectedChunk: IChunk) => { +export const buildChunkHighlights = ( + selectedChunk: IChunk, + size: { width: number; height: number }, +) => { return Array.isArray(selectedChunk?.positions) && selectedChunk.positions.every((x) => Array.isArray(x)) ? selectedChunk?.positions?.map((x) => { - const actualPositions = x.map((y, index) => - index !== 0 ? y / 0.7 : y, - ); const boundingRect = { - width: 849, - height: 1200, - x1: actualPositions[1], - x2: actualPositions[2], - y1: actualPositions[3], - y2: actualPositions[4], + width: size.width, + height: size.height, + x1: x[1], + x2: x[2], + y1: x[3], + y2: x[4], }; return { id: uuid(),