PdfViewer.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import React, { useEffect } from 'react';
  2. import queryString from 'query-string';
  3. import config from '../config';
  4. import apiPath from '../constants/apiPath';
  5. import { initialPdfFile, fetchXfdf } from '../apis';
  6. import PdfPages from './PdfPages';
  7. import { fetchPdf } from '../helpers/pdf';
  8. import {
  9. parseAnnotationFromXml,
  10. parseFormElementFromXml,
  11. } from '../helpers/annotation';
  12. import { parseWatermarkFromXml } from '../helpers/watermark';
  13. import useActions from '../actions';
  14. import useStore from '../store';
  15. const PdfViewer: React.FC = () => {
  16. const [{ viewport, pdf, scale }, dispatch] = useStore();
  17. const {
  18. setTotalPage,
  19. setPdf,
  20. setProgress,
  21. setViewport,
  22. setCurrentPage,
  23. setInfo,
  24. addAnnots,
  25. changeScale,
  26. updateWatermark,
  27. } = useActions(dispatch);
  28. const setLoadingProgress = (totalSize: number) => (
  29. progress: ProgressType,
  30. ): void => {
  31. setProgress({
  32. total: totalSize,
  33. loaded: progress.loaded,
  34. });
  35. };
  36. const getViewport = async (pdfEle: PdfType, s: number): Promise<void> => {
  37. if (!pdfEle) return;
  38. const page = await pdfEle.getPage(1);
  39. if (!page) return;
  40. const iViewport = page.getViewport({ scale: s });
  41. iViewport.width = Math.round(iViewport.width);
  42. iViewport.height = Math.round(iViewport.height);
  43. setViewport(iViewport);
  44. };
  45. const getXfdfFile = (token: string): void => {
  46. fetchXfdf(token)
  47. .then((xfdf) => {
  48. const annotations = parseAnnotationFromXml(xfdf);
  49. const forms = parseFormElementFromXml(xfdf);
  50. const watermark = parseWatermarkFromXml(xfdf);
  51. if (watermark.obj_attr.type) {
  52. addAnnots([...annotations, ...forms, watermark], false);
  53. updateWatermark(watermark.obj_attr);
  54. } else {
  55. addAnnots([...annotations, ...forms], false);
  56. }
  57. })
  58. .catch((error) => {
  59. console.log(error);
  60. });
  61. };
  62. const pdfStarter = async (): Promise<void> => {
  63. const parsed = queryString.parse(window.location.search);
  64. if (parsed.token) {
  65. const token = parsed.token as string;
  66. const result = (await initialPdfFile(token)) as {
  67. data: { transaction_id: string; size: number };
  68. };
  69. getXfdfFile(token);
  70. setInfo({
  71. token: parsed.token,
  72. id: result.data.transaction_id,
  73. });
  74. const iPdf = await fetchPdf(
  75. `${config.API_HOST}${apiPath.getOriginalPdfFile}?transaction_id=${result.data.transaction_id}`,
  76. setLoadingProgress(result.data.size),
  77. );
  78. if (!iPdf) return;
  79. setTotalPage(iPdf.numPages);
  80. setPdf(iPdf);
  81. const page = (await iPdf.getPage(1)) as PdfPageType;
  82. if (!page) return;
  83. const iViewport = page.getViewport({ scale: 1 });
  84. iViewport.width = Math.round(iViewport.width);
  85. iViewport.height = Math.round(iViewport.height);
  86. const screenWidth = window.document.body.offsetWidth - 286;
  87. const originPdfWidth = iViewport.width;
  88. const rate = (screenWidth / originPdfWidth).toFixed(2);
  89. changeScale(rate);
  90. }
  91. };
  92. const scrollToUpdate = (state: ScrollStateType): void => {
  93. const ele: HTMLDivElement = document.getElementById(
  94. 'page_1',
  95. ) as HTMLDivElement;
  96. const pageNum = Math.round(
  97. (state.lastY + ele.offsetHeight / 1.4) / (ele.offsetHeight + 50),
  98. );
  99. setCurrentPage(pageNum);
  100. };
  101. useEffect(() => {
  102. pdfStarter();
  103. }, []);
  104. useEffect(() => {
  105. if (pdf) {
  106. getViewport(pdf, scale);
  107. }
  108. }, [scale]);
  109. return viewport.width ? <PdfPages scrollToUpdate={scrollToUpdate} /> : null;
  110. };
  111. export default PdfViewer;