feat: hightlight pdf
This commit is contained in:
parent
25187b1ad7
commit
a14c14ee4c
5 changed files with 60 additions and 7 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
import { useSize } from 'ahooks';
|
import { useSize } from 'ahooks';
|
||||||
|
import { CustomTextRenderer } from 'node_modules/react-pdf/dist/esm/shared/types';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
|
|
||||||
export const useDocumentResizeObserver = () => {
|
export const useDocumentResizeObserver = () => {
|
||||||
|
|
@ -18,3 +19,27 @@ export const useDocumentResizeObserver = () => {
|
||||||
|
|
||||||
return { containerWidth, setContainerRef };
|
return { containerWidth, setContainerRef };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function highlightPattern(text: string, pattern: string, pageNumber: number) {
|
||||||
|
const finalText = '';
|
||||||
|
console.info(text);
|
||||||
|
if (pageNumber === 2) {
|
||||||
|
return `<mark>${text}</mark>`;
|
||||||
|
}
|
||||||
|
if (text.trim() !== '' && pattern.match(text)) {
|
||||||
|
// return pattern.replace(text, (value) => `<mark>${value}</mark>`);
|
||||||
|
return `<mark>${text}</mark>`;
|
||||||
|
}
|
||||||
|
return text.replace(pattern, (value) => `<mark>${value}</mark>`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useHighlightText = (searchText: string = '') => {
|
||||||
|
const textRenderer: CustomTextRenderer = useCallback(
|
||||||
|
(textItem) => {
|
||||||
|
return highlightPattern(textItem.str, searchText, textItem.pageNumber);
|
||||||
|
},
|
||||||
|
[searchText],
|
||||||
|
);
|
||||||
|
|
||||||
|
return textRenderer;
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,10 @@ import { Document, Page, pdfjs } from 'react-pdf';
|
||||||
|
|
||||||
import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
|
import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
|
||||||
import 'react-pdf/dist/esm/Page/TextLayer.css';
|
import 'react-pdf/dist/esm/Page/TextLayer.css';
|
||||||
import { useDocumentResizeObserver } from './hooks';
|
import { useDocumentResizeObserver, useHighlightText } from './hooks';
|
||||||
|
|
||||||
|
import { Spin } from 'antd';
|
||||||
|
import { useGetSelectedChunk } from '../../hooks';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||||
|
|
@ -14,10 +16,17 @@ pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||||
import.meta.url,
|
import.meta.url,
|
||||||
).toString();
|
).toString();
|
||||||
|
|
||||||
const DocumentPreview = () => {
|
interface IProps {
|
||||||
|
selectedChunkId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DocumentPreview = ({ selectedChunkId }: IProps) => {
|
||||||
const [numPages, setNumPages] = useState<number>();
|
const [numPages, setNumPages] = useState<number>();
|
||||||
const { documentId } = useGetKnowledgeSearchParams();
|
const { documentId } = useGetKnowledgeSearchParams();
|
||||||
const { containerWidth, setContainerRef } = useDocumentResizeObserver();
|
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 {
|
function onDocumentLoadSuccess({ numPages }: { numPages: number }): void {
|
||||||
setNumPages(numPages);
|
setNumPages(numPages);
|
||||||
|
|
@ -29,12 +38,17 @@ const DocumentPreview = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={setContainerRef} className={styles.documentContainer}>
|
<div ref={setContainerRef} className={styles.documentContainer}>
|
||||||
<Document file={url} onLoadSuccess={onDocumentLoadSuccess}>
|
<Document
|
||||||
|
file={url}
|
||||||
|
onLoadSuccess={onDocumentLoadSuccess}
|
||||||
|
loading={<Spin></Spin>}
|
||||||
|
>
|
||||||
{Array.from(new Array(numPages), (el, index) => (
|
{Array.from(new Array(numPages), (el, index) => (
|
||||||
<Page
|
<Page
|
||||||
key={`page_${index + 1}`}
|
key={`page_${index + 1}`}
|
||||||
pageNumber={index + 1}
|
pageNumber={index + 1}
|
||||||
width={containerWidth}
|
width={containerWidth}
|
||||||
|
customTextRenderer={textRenderer}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Document>
|
</Document>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
import { IChunk, IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { useSelector } from 'umi';
|
import { useSelector } from 'umi';
|
||||||
|
|
||||||
|
|
@ -9,6 +9,13 @@ export const useSelectDocumentInfo = () => {
|
||||||
return documentInfo;
|
return documentInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useSelectChunkList = () => {
|
||||||
|
const chunkList: IChunk[] = useSelector(
|
||||||
|
(state: any) => state.chunkModel.data,
|
||||||
|
);
|
||||||
|
return chunkList;
|
||||||
|
};
|
||||||
|
|
||||||
export const useHandleChunkCardClick = () => {
|
export const useHandleChunkCardClick = () => {
|
||||||
const [selectedChunkId, setSelectedChunkId] = useState<string>('');
|
const [selectedChunkId, setSelectedChunkId] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -18,3 +25,8 @@ export const useHandleChunkCardClick = () => {
|
||||||
|
|
||||||
return { handleChunkCardClick, selectedChunkId };
|
return { handleChunkCardClick, selectedChunkId };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useGetSelectedChunk = (selectedChunkId: string) => {
|
||||||
|
const chunkList: IChunk[] = useSelectChunkList();
|
||||||
|
return chunkList.find((x) => x.chunk_id === selectedChunkId);
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,9 @@ const Chunk = () => {
|
||||||
|
|
||||||
{documentInfo.type === 'pdf' && (
|
{documentInfo.type === 'pdf' && (
|
||||||
<section className={styles.documentPreview}>
|
<section className={styles.documentPreview}>
|
||||||
<DocumentPreview></DocumentPreview>
|
<DocumentPreview
|
||||||
|
selectedChunkId={selectedChunkId}
|
||||||
|
></DocumentPreview>
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { BaseState } from '@/interfaces/common';
|
import { BaseState } from '@/interfaces/common';
|
||||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
import { IChunk, IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||||
import kbService from '@/services/kbService';
|
import kbService from '@/services/kbService';
|
||||||
import { message } from 'antd';
|
import { message } from 'antd';
|
||||||
import { pick } from 'lodash';
|
import { pick } from 'lodash';
|
||||||
|
|
@ -7,7 +7,7 @@ import { pick } from 'lodash';
|
||||||
import { DvaModel } from 'umi';
|
import { DvaModel } from 'umi';
|
||||||
|
|
||||||
export interface ChunkModelState extends BaseState {
|
export interface ChunkModelState extends BaseState {
|
||||||
data: any[];
|
data: IChunk[];
|
||||||
total: number;
|
total: number;
|
||||||
isShowCreateModal: boolean;
|
isShowCreateModal: boolean;
|
||||||
chunk_id: string;
|
chunk_id: string;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue