PdfPages.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import React, {
  2. useEffect, useState, useRef,
  3. } from 'react';
  4. import _ from 'lodash';
  5. import { AnnotationType, ScrollStateType } from '../constants/type';
  6. import Page from '../components/Page';
  7. import Viewer from '../components/Viewer';
  8. import Annotation from './Annotation';
  9. import { watchScroll } from '../helpers/utility';
  10. import { getPdfPage } from '../helpers/pdf';
  11. import useStore from '../store';
  12. type Props = {
  13. scrollToUpdate: (state: ScrollStateType) => void;
  14. };
  15. const PdfPages: React.FunctionComponent<Props> = ({
  16. scrollToUpdate,
  17. }: Props) => {
  18. const [elements, setElement] = useState<React.ReactNode[]>([]);
  19. const containerRef = useRef<HTMLDivElement>(null);
  20. const [{
  21. totalPage,
  22. currentPage,
  23. viewport,
  24. pdf,
  25. rotation,
  26. displayMode,
  27. annotations,
  28. scale,
  29. }] = useStore();
  30. const getAnnotations = (arr: AnnotationType[], pageNum: number): any[] => {
  31. const result: any[] = [];
  32. arr.forEach((ele: AnnotationType, index: number) => {
  33. const page = ele.obj_attr ? ele.obj_attr.page as number + 1 : 0;
  34. if (page === pageNum) {
  35. result.push(<Annotation key={`annotations_${pageNum + index}`} scale={scale} index={index} {...ele} />);
  36. }
  37. });
  38. return result;
  39. };
  40. const createPages = (): void => {
  41. const pagesContent: React.ReactNode[] = [];
  42. for (let i = 1; i <= totalPage; i += 1) {
  43. const annotationElements = getAnnotations(annotations, i);
  44. const component = (
  45. <Page
  46. key={`page-${i}`}
  47. pageNum={i}
  48. renderingState={_.range(1, 4).includes(i) ? 'RENDERING' : 'LOADING'}
  49. viewport={viewport}
  50. getPage={(): Promise<any> => getPdfPage(pdf, i)}
  51. rotation={rotation}
  52. annotations={annotationElements}
  53. />
  54. );
  55. pagesContent.push(component);
  56. }
  57. setElement(pagesContent);
  58. };
  59. const updatePages = (): void => {
  60. const renderingIndexQueue = _.range(currentPage - 1, currentPage + 2);
  61. let index = currentPage - 4;
  62. const end = currentPage + 3;
  63. while (currentPage) {
  64. if (elements[index]) {
  65. const pageNum = index + 1;
  66. const annotationElements = getAnnotations(annotations, pageNum);
  67. elements[index] = (
  68. <Page
  69. key={`page-${pageNum}`}
  70. pageNum={pageNum}
  71. renderingState={renderingIndexQueue.includes(pageNum) ? 'RENDERING' : 'LOADING'}
  72. viewport={viewport}
  73. getPage={(): Promise<any> => getPdfPage(pdf, pageNum)}
  74. rotation={rotation}
  75. annotations={annotationElements}
  76. />
  77. );
  78. }
  79. index += 1;
  80. if (index >= end) break;
  81. }
  82. if (elements.length) {
  83. setElement([...elements]);
  84. }
  85. };
  86. useEffect(() => {
  87. createPages();
  88. watchScroll(containerRef.current, scrollToUpdate);
  89. }, []);
  90. useEffect(() => {
  91. updatePages();
  92. }, [currentPage, viewport, rotation, annotations]);
  93. return (
  94. <Viewer
  95. ref={containerRef}
  96. viewport={viewport}
  97. rotation={rotation}
  98. displayMode={displayMode}
  99. >
  100. {elements}
  101. </Viewer>
  102. );
  103. };
  104. export default PdfPages;