123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- import React, { useEffect, useState, useRef, useCallback } from 'react';
- import { useTranslation } from 'react-i18next';
- import Typography from '../Typography';
- import Item from '../AnnotationItem';
- import { watchScroll } from '../../helpers/utility';
- import { getAnnotationText } from '../../helpers/annotation';
- import { Body } from '../../global/sidebarStyled';
- type Props = {
- isActive?: boolean;
- annotations: AnnotationType[];
- viewport: ViewportType;
- scale: number;
- pdf: any;
- };
- const AnnotationList: React.FC<Props> = ({
- isActive = false,
- annotations,
- viewport,
- scale,
- pdf,
- }: Props) => {
- const { t } = useTranslation('sidebar');
- const [renderQueue, setQueue] = useState<AnnotationType[]>([]);
- const containerRef = useRef<HTMLDivElement>(null);
- const innerRef = useRef<HTMLDivElement>(null);
- const getText = async (
- page: number,
- position: PositionType[]
- ): Promise<any> => {
- const text = await getAnnotationText({
- pdf,
- viewport,
- scale,
- page,
- coords: position,
- });
- return text;
- };
- const scrollUpdate = useCallback(
- (state: ScrollStateType): void => {
- const innerHeight = innerRef.current?.offsetHeight || 0;
- const wrapperHeight = containerRef.current?.offsetHeight || 0;
- if (
- wrapperHeight + state.lastY >= innerHeight &&
- renderQueue.length !== annotations.length
- ) {
- const start = renderQueue.length;
- const end = renderQueue.length + 10;
- const newQueue = [...renderQueue, ...annotations.slice(start, end)];
- setQueue(newQueue);
- }
- },
- [renderQueue, annotations]
- );
- useEffect(() => {
- const state = watchScroll(containerRef.current, scrollUpdate);
- return (): void => {
- state.subscriber.unsubscribe();
- };
- }, [scrollUpdate]);
- useEffect(() => {
- if (isActive) {
- setQueue(annotations.slice(0, 10));
- }
- }, [isActive, annotations]);
- return (
- <Body ref={containerRef}>
- <div ref={innerRef}>
- <Typography light align="left">
- {`${annotations.length} ${t('annotation')}`}
- </Typography>
- {isActive &&
- renderQueue.map((ele, index) => {
- const key = `annot_item_${index}`;
- const {
- obj_type,
- obj_attr: { page, bdcolor, position, transparency },
- } = ele;
- const actualPage = page + 1;
- const prevAnnot = annotations[index - 1];
- const prevPage =
- index > 0 && prevAnnot ? prevAnnot.obj_attr.page + 1 : -1;
- return (
- <Item
- key={key}
- type={obj_type}
- page={actualPage}
- bdcolor={bdcolor || ''}
- transparency={transparency || 0}
- getText={(): Promise<any> =>
- getText(actualPage, position as PositionType[])
- }
- showPageNum={actualPage !== prevPage}
- />
- );
- })}
- </div>
- </Body>
- );
- };
- export default AnnotationList;
|