import React, { useEffect, useRef } from 'react'; import queryString from 'query-string'; import config from '../config'; import apiPath from '../constants/apiPath'; import { initialPdfFile } from '../apis'; import PdfPages from './PdfPages'; import { fetchPdf } from '../helpers/pdf'; import { ProgressType, ScrollStateType } from '../constants/type'; import { scrollIntoView } from '../helpers/utility'; import { parseAnnotationFromXml, fetchXfdf } from '../helpers/annotation'; import useActions from '../actions'; import useStore from '../store'; const PdfViewer: React.FunctionComponent = () => { const [{ viewport, pdf, scale, currentPage, totalPage, }, dispatch] = useStore(); const { setTotalPage, setPdf, setProgress, setViewport, setCurrentPage, setInfo, addAnnotation, changeScale, } = useActions(dispatch); const currentPageRef = useRef(0); const setLoadingProgress = (totalSize: number) => (progress: ProgressType): void => { setProgress({ total: totalSize, loaded: progress.loaded, }); }; const getViewport = async (pdfEle: any, s: number): Promise => { const page = await pdfEle.getPage(1); const iViewport = page.getViewport({ scale: s }); iViewport.width = Math.round(iViewport.width); iViewport.height = Math.round(iViewport.height); setViewport(iViewport); }; const pdfGenerator = async (): Promise => { const parsed = queryString.parse(window.location.search); const result = await initialPdfFile(parsed.token as string); fetchXfdf(parsed.token as string).then((res) => { if (res) { const annot = parseAnnotationFromXml(res); addAnnotation(annot, false); } }); if (result.data) { setInfo({ token: parsed.token, id: result.data.transaction_id, }); const iPdf = await fetchPdf( `${config.API_HOST}${apiPath.getOriginalPdfFile}?transaction_id=${result.data.transaction_id}`, setLoadingProgress(result.data.size), ); setTotalPage(iPdf.numPages); setPdf(iPdf); const page = await iPdf.getPage(1); const iViewport = page.getViewport({ scale: 1 }); iViewport.width = Math.round(iViewport.width); iViewport.height = Math.round(iViewport.height); const screenwidth = window.screen.width - 200; const originPdfWidth = iViewport.width / 1; const rate = screenwidth / originPdfWidth; changeScale(rate); } }; const changePdfContainerScale = (): void => { for (let i = 1; i <= totalPage; i += 1) { const ele: HTMLDivElement = document.getElementById(`page_${i}`) as HTMLDivElement; if (ele) { ele.style.width = `${viewport.width}px`; ele.style.height = `${viewport.height}px`; if (i === currentPageRef.current) { scrollIntoView(ele); } } } }; const scrollToUpdate = (state: ScrollStateType): void => { const ele: HTMLDivElement = document.getElementById('page_1') as HTMLDivElement; const page = Math.round((state.lastY + ele.offsetHeight / 1.4) / (ele.offsetHeight + 40)); if (page !== currentPageRef.current) { setCurrentPage(page); } }; useEffect(() => { pdfGenerator(); }, []); useEffect(() => { currentPageRef.current = currentPage; }, [currentPage]); useEffect(() => { if (pdf) { changePdfContainerScale(); } }, [viewport]); useEffect(() => { if (pdf) { getViewport(pdf, scale); } }, [scale]); return ( viewport.width ? ( ) : null ); }; export default PdfViewer;