feat: set width of chunk text to 100% and add Skeleton to Preview of document and remove react-pdf (#94)
* feat: remove react-pdf * feat: add Skeleton to Preview of document * feat: set width of chunk text to 100%
This commit is contained in:
@@ -13,6 +13,9 @@
|
||||
color: red;
|
||||
font-style: normal;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
caption {
|
||||
color: @blurBackground;
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
export const testHighlights = [
|
||||
{
|
||||
content: {
|
||||
text: '实验证明,由氧氯化锆锂和高镍三元正极组成的全固态锂电池展示了极为优异的性能:在12 分钟快速充电的条件下,该电池仍然成功地在室温稳定循环2000 圈以上。',
|
||||
},
|
||||
position: {
|
||||
boundingRect: {
|
||||
x1: 219.7,
|
||||
// x1: 419.7,
|
||||
y1: 204.3,
|
||||
// y1: 304.3,
|
||||
x2: 547.0,
|
||||
// x2: 747.0,
|
||||
y2: 264.0,
|
||||
// y2: 364.0,
|
||||
},
|
||||
rects: [
|
||||
// {
|
||||
// x1: 219.7,
|
||||
// // x1: 419.7,
|
||||
// y1: 204.3,
|
||||
// // y1: 304.3,
|
||||
// x2: 547.0,
|
||||
// // x2: 747.0,
|
||||
// y2: 264.0,
|
||||
// // y2: 364.0,
|
||||
// width: 849,
|
||||
// height: 1200,
|
||||
// },
|
||||
],
|
||||
pageNumber: 9,
|
||||
},
|
||||
comment: {
|
||||
text: 'Flow or TypeScript?',
|
||||
emoji: '🔥',
|
||||
},
|
||||
id: 'jsdlihdkghergjl',
|
||||
},
|
||||
{
|
||||
content: {
|
||||
text: '图2:乘联会预计6 月新能源乘用车厂商批发销量74 万辆,环比增长10%,同比增长30%。',
|
||||
},
|
||||
position: {
|
||||
boundingRect: {
|
||||
x1: 219.0,
|
||||
x2: 546.0,
|
||||
y1: 616.0,
|
||||
y2: 674.7,
|
||||
},
|
||||
rects: [],
|
||||
pageNumber: 6,
|
||||
},
|
||||
comment: {
|
||||
text: 'Flow or TypeScript?',
|
||||
emoji: '🔥',
|
||||
},
|
||||
id: 'bfdbtymkhjildbfghserrgrt',
|
||||
},
|
||||
{
|
||||
content: {
|
||||
text: '图2:乘联会预计6 月新能源乘用车厂商批发销量74 万辆,环比增长10%,同比增长30%。',
|
||||
},
|
||||
position: {
|
||||
boundingRect: {
|
||||
x1: 73.7,
|
||||
x2: 391.7,
|
||||
y1: 570.3,
|
||||
y2: 676.3,
|
||||
},
|
||||
rects: [],
|
||||
pageNumber: 1,
|
||||
},
|
||||
comment: {
|
||||
text: '',
|
||||
emoji: '',
|
||||
},
|
||||
id: 'fgnhxdvsesgmghyu',
|
||||
},
|
||||
].map((x) => {
|
||||
const boundingRect = x.position.boundingRect;
|
||||
const ret: any = {
|
||||
width: 849,
|
||||
height: 1200,
|
||||
};
|
||||
Object.entries(boundingRect).forEach(([key, value]) => {
|
||||
ret[key] = value / 0.7;
|
||||
});
|
||||
return { ...x, position: { ...x.position, boundingRect: ret, rects: [ret] } };
|
||||
});
|
||||
@@ -1,59 +0,0 @@
|
||||
import { useGetKnowledgeSearchParams } from '@/hooks/knowledgeHook';
|
||||
import { api_host } from '@/utils/api';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { Document, Page, pdfjs } from 'react-pdf';
|
||||
|
||||
import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
|
||||
import 'react-pdf/dist/esm/Page/TextLayer.css';
|
||||
import { useDocumentResizeObserver, useHighlightText } from './hooks';
|
||||
|
||||
import { Spin } from 'antd';
|
||||
import { useGetSelectedChunk } from '../../hooks';
|
||||
import styles from './index.less';
|
||||
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||
'pdfjs-dist/build/pdf.worker.min.js',
|
||||
import.meta.url,
|
||||
).toString();
|
||||
|
||||
interface IProps {
|
||||
selectedChunkId: string;
|
||||
}
|
||||
|
||||
const DocumentPreview = ({ selectedChunkId }: IProps) => {
|
||||
const [numPages, setNumPages] = useState<number>();
|
||||
const { documentId } = useGetKnowledgeSearchParams();
|
||||
const { containerWidth, setContainerRef } = useDocumentResizeObserver();
|
||||
const selectedChunk = useGetSelectedChunk(selectedChunkId);
|
||||
console.info(selectedChunk?.content_with_weight);
|
||||
const textRenderer = useHighlightText(selectedChunk?.content_with_weight);
|
||||
|
||||
function onDocumentLoadSuccess({ numPages }: { numPages: number }): void {
|
||||
setNumPages(numPages);
|
||||
}
|
||||
|
||||
const url = useMemo(() => {
|
||||
return `${api_host}/document/get/${documentId}`;
|
||||
}, [documentId]);
|
||||
|
||||
return (
|
||||
<div ref={setContainerRef} className={styles.documentContainer}>
|
||||
<Document
|
||||
file={url}
|
||||
onLoadSuccess={onDocumentLoadSuccess}
|
||||
loading={<Spin></Spin>}
|
||||
>
|
||||
{Array.from(new Array(numPages), (el, index) => (
|
||||
<Page
|
||||
key={`page_${index + 1}`}
|
||||
pageNumber={index + 1}
|
||||
width={containerWidth}
|
||||
customTextRenderer={textRenderer}
|
||||
/>
|
||||
))}
|
||||
</Document>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DocumentPreview;
|
||||
@@ -1,15 +1,14 @@
|
||||
import { Spin } from 'antd';
|
||||
import { Skeleton } from 'antd';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import {
|
||||
AreaHighlight,
|
||||
Highlight,
|
||||
NewHighlight,
|
||||
IHighlight,
|
||||
PdfHighlighter,
|
||||
PdfLoader,
|
||||
Popup,
|
||||
Tip,
|
||||
} from 'react-pdf-highlighter';
|
||||
import { useGetChunkHighlights, useGetSelectedChunk } from '../../hooks';
|
||||
import { useGetChunkHighlights } from '../../hooks';
|
||||
import { useGetDocumentUrl } from './hooks';
|
||||
|
||||
import styles from './index.less';
|
||||
@@ -18,8 +17,6 @@ interface IProps {
|
||||
selectedChunkId: string;
|
||||
}
|
||||
|
||||
const getNextId = () => String(Math.random()).slice(2);
|
||||
|
||||
const HighlightPopup = ({
|
||||
comment,
|
||||
}: {
|
||||
@@ -33,70 +30,10 @@ const HighlightPopup = ({
|
||||
|
||||
const Preview = ({ selectedChunkId }: IProps) => {
|
||||
const url = useGetDocumentUrl();
|
||||
const selectedChunk = useGetSelectedChunk(selectedChunkId);
|
||||
|
||||
// const [state, setState] = useState<any>(testHighlights);
|
||||
const state = useGetChunkHighlights(selectedChunkId);
|
||||
const ref = useRef<(highlight: IHighlight) => void>(() => {});
|
||||
|
||||
const ref = useRef((highlight: any) => {});
|
||||
|
||||
const parseIdFromHash = () =>
|
||||
document.location.hash.slice('#highlight-'.length);
|
||||
|
||||
const resetHash = () => {
|
||||
document.location.hash = '';
|
||||
};
|
||||
|
||||
const getHighlightById = (id: string) => {
|
||||
const highlights = state;
|
||||
|
||||
return highlights.find((highlight: any) => highlight.id === id);
|
||||
};
|
||||
|
||||
// let scrollViewerTo = (highlight: any) => {};
|
||||
|
||||
let scrollToHighlightFromHash = () => {
|
||||
const highlight = getHighlightById(parseIdFromHash());
|
||||
|
||||
if (highlight) {
|
||||
ref.current(highlight);
|
||||
}
|
||||
};
|
||||
|
||||
const addHighlight = (highlight: NewHighlight) => {
|
||||
const highlights = state;
|
||||
|
||||
console.log('Saving highlight', highlight);
|
||||
|
||||
// setState([{ ...highlight, id: getNextId() }, ...highlights]);
|
||||
};
|
||||
|
||||
const updateHighlight = (
|
||||
highlightId: string,
|
||||
position: Object,
|
||||
content: Object,
|
||||
) => {
|
||||
console.log('Updating highlight', highlightId, position, content);
|
||||
|
||||
// setState(
|
||||
// state.map((h: any) => {
|
||||
// const {
|
||||
// id,
|
||||
// position: originalPosition,
|
||||
// content: originalContent,
|
||||
// ...rest
|
||||
// } = h;
|
||||
// return id === highlightId
|
||||
// ? {
|
||||
// id,
|
||||
// position: { ...originalPosition, ...position },
|
||||
// content: { ...originalContent, ...content },
|
||||
// ...rest,
|
||||
// }
|
||||
// : h;
|
||||
// }),
|
||||
// );
|
||||
};
|
||||
const resetHash = () => {};
|
||||
|
||||
useEffect(() => {
|
||||
if (state.length > 0) {
|
||||
@@ -106,35 +43,16 @@ const Preview = ({ selectedChunkId }: IProps) => {
|
||||
|
||||
return (
|
||||
<div className={styles.documentContainer}>
|
||||
<PdfLoader url={url} beforeLoad={<Spin />}>
|
||||
<PdfLoader url={url} beforeLoad={<Skeleton active />}>
|
||||
{(pdfDocument) => (
|
||||
<PdfHighlighter
|
||||
pdfDocument={pdfDocument}
|
||||
enableAreaSelection={(event) => event.altKey}
|
||||
onScrollChange={resetHash}
|
||||
// pdfScaleValue="page-width"
|
||||
|
||||
scrollRef={(scrollTo) => {
|
||||
// scrollViewerTo = scrollTo;
|
||||
ref.current = scrollTo;
|
||||
|
||||
scrollToHighlightFromHash();
|
||||
}}
|
||||
onSelectionFinished={(
|
||||
position,
|
||||
content,
|
||||
hideTipAndSelection,
|
||||
transformSelection,
|
||||
) => (
|
||||
<Tip
|
||||
onOpen={transformSelection}
|
||||
onConfirm={(comment) => {
|
||||
addHighlight({ content, position, comment });
|
||||
|
||||
hideTipAndSelection();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
onSelectionFinished={() => null}
|
||||
highlightTransform={(
|
||||
highlight,
|
||||
index,
|
||||
@@ -158,13 +76,7 @@ const Preview = ({ selectedChunkId }: IProps) => {
|
||||
<AreaHighlight
|
||||
isScrolledTo={isScrolledTo}
|
||||
highlight={highlight}
|
||||
onChange={(boundingRect) => {
|
||||
updateHighlight(
|
||||
highlight.id,
|
||||
{ boundingRect: viewportToScaled(boundingRect) },
|
||||
{ image: screenshot(boundingRect) },
|
||||
);
|
||||
}}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -172,7 +84,7 @@ const Preview = ({ selectedChunkId }: IProps) => {
|
||||
<Popup
|
||||
popupContent={<HighlightPopup {...highlight} />}
|
||||
onMouseOver={(popupContent) =>
|
||||
setTip(highlight, (highlight: any) => popupContent)
|
||||
setTip(highlight, () => popupContent)
|
||||
}
|
||||
onMouseOut={hideTip}
|
||||
key={index}
|
||||
|
||||
Reference in New Issue
Block a user