PdfViewer.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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: any, s: number): Promise<any> => {
  37. const page = await pdfEle.getPage(1);
  38. const iViewport = page.getViewport({ scale: s });
  39. iViewport.width = Math.round(iViewport.width);
  40. iViewport.height = Math.round(iViewport.height);
  41. setViewport(iViewport);
  42. };
  43. const getXfdfFile = (token: string): void => {
  44. fetchXfdf(token)
  45. .then(xfdf => {
  46. const annotations = parseAnnotationFromXml(xfdf);
  47. const forms = parseFormElementFromXml(xfdf);
  48. const watermark = parseWatermarkFromXml(xfdf);
  49. if (watermark.obj_attr.type) {
  50. addAnnots([...annotations, ...forms, watermark], false);
  51. updateWatermark(watermark.obj_attr);
  52. } else {
  53. addAnnots([...annotations, ...forms], false);
  54. }
  55. })
  56. .catch(error => {
  57. console.log(error);
  58. });
  59. };
  60. const pdfStarter = async (): Promise<any> => {
  61. const parsed = queryString.parse(window.location.search);
  62. if (parsed.token) {
  63. const token = parsed.token as string;
  64. const result = await initialPdfFile(token);
  65. getXfdfFile(token);
  66. setInfo({
  67. token: parsed.token,
  68. id: result.data.transaction_id,
  69. });
  70. const iPdf = await fetchPdf(
  71. `${config.API_HOST}${apiPath.getOriginalPdfFile}?transaction_id=${result.data.transaction_id}`,
  72. setLoadingProgress(result.data.size)
  73. );
  74. setTotalPage(iPdf.numPages);
  75. setPdf(iPdf);
  76. const page = await iPdf.getPage(1);
  77. const iViewport = page.getViewport({ scale: 1 });
  78. iViewport.width = Math.round(iViewport.width);
  79. iViewport.height = Math.round(iViewport.height);
  80. const screenWidth = window.document.body.offsetWidth - 286;
  81. const originPdfWidth = iViewport.width;
  82. const rate = (screenWidth / originPdfWidth).toFixed(2);
  83. changeScale(rate);
  84. }
  85. };
  86. const scrollToUpdate = (state: ScrollStateType): void => {
  87. const ele: HTMLDivElement = document.getElementById(
  88. 'page_1'
  89. ) as HTMLDivElement;
  90. const pageNum = Math.round(
  91. (state.lastY + ele.offsetHeight / 1.4) / (ele.offsetHeight + 50)
  92. );
  93. setCurrentPage(pageNum);
  94. };
  95. useEffect(() => {
  96. pdfStarter();
  97. }, []);
  98. useEffect(() => {
  99. if (pdf) {
  100. getViewport(pdf, scale);
  101. }
  102. }, [scale]);
  103. return viewport.width ? <PdfPages scrollToUpdate={scrollToUpdate} /> : null;
  104. };
  105. export default PdfViewer;