huridocs/uwazi

View on GitHub
app/react/PDF/components/PDFPage.js

Summary

Maintainability
A
0 mins
Test Coverage
B
89%
Definition for rule 'node/no-restricted-import' was not found.
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { isClient } from 'app/utils';
import { PageReferences } from 'app/Viewer/components/PageReferences';
import { PageSelections } from 'app/Viewer/components/PageSelections';
import { calculateScaling } from 'V2/Components/PDFViewer';
import { atomStore, pdfScaleAtom } from 'V2/atoms';
import PDFJS, { EventBus } from '../PDFJS';
 
class PDFPage extends Component {
constructor(props) {
super(props);
this.state = { rendered: false };
}
 
componentDidMount() {
this.scrollCallback = this.scroll.bind(this);
 
if (this.pageContainer && this.pageShouldRender()) {
this.renderPage();
}
 
this.props.getViewportContainer().addEventListener('scroll', this.scrollCallback);
this._mounted = true;
}
 
componentWillUnmount() {
if (this.pdfPageView) {
this.pdfPageView.destroy();
}
this.props.getViewportContainer().removeEventListener('scroll', this.scrollCallback);
this._mounted = false;
}
 
scroll() {
if (this.pageShouldRender() && !this.state.rendered) {
this.renderPage();
}
 
if (!this.pageShouldRender() && this.pdfPageView) {
this.pdfPageView.cancelRendering();
this.pdfPageView.destroy();
if (this.state.rendered) {
this.props.onUnload(this.props.page);
}
this.setState({ rendered: false });
}
}
 
pageShouldRender() {
const pageRectangle = this.pageContainer.getBoundingClientRect();
const vWidth = window.innerWidth || document.documentElement.clientWidth;
const vHeight = window.innerHeight || document.documentElement.clientHeight;
 
if (
pageRectangle.right < 0 ||
pageRectangle.bottom < -500 ||
pageRectangle.left > vWidth ||
pageRectangle.top > vHeight + 500
) {
this.props.onHidden(this.props.page);
return false;
}
this.checkVisibility(pageRectangle);
return true;
}
 
checkVisibility(pageRectangle) {
const viewportRect = this.props.getViewportContainer().getBoundingClientRect();
 
const relativeElementRect = {
top: pageRectangle.top - viewportRect.top,
bottom: pageRectangle.bottom,
};
 
const offsetTop = relativeElementRect.top < 0 ? -relativeElementRect.top : 0;
const offsetBottom =
pageRectangle.bottom - viewportRect.bottom > 0
? pageRectangle.bottom - viewportRect.bottom
: 0;
const visibility = pageRectangle.height - offsetTop - offsetBottom;
 
if (visibility > 0) {
this.props.onVisible(this.props.page, visibility);
}
 
if (visibility < 0) {
this.props.onHidden(this.props.page);
}
}
 
renderReferences() {
if (this.state.rendered) {
return (
<>
<PageSelections />
<PageReferences page={this.props.page} onClick={this.props.highlightReference} />
</>
);
}
 
return false;
}
 
renderPage() {
if (!this.state.rendered && this.pdfPageView) {
this.props.onLoading(this.props.page);
this.pdfPageView.draw().catch(e => e);
this.setState({ rendered: true });
 
return;
}
if (!this.state.rendered) {
this.props.onLoading(this.props.page);
this.setState({ rendered: true });
this.props.pdf.getPage(this.props.page).then(page => {
const originalViewport = page.getViewport({ scale: 1 });
const scale = calculateScaling(
originalViewport.width * PDFJS.PixelsPerInch.PDF_TO_CSS_UNITS,
this.props.containerWidth
);
const defaultViewport = page.getViewport({ scale });
 
this.pdfPageView = new PDFJS.PDFPageView({
container: this.pageContainer,
id: this.props.page,
scale,
defaultViewport,
textLayerMode: 1,
eventBus: new EventBus(),
});
 
atomStore.set(pdfScaleAtom, scale);
 
this.pdfPageView.setPdfPage(page);
this.pdfPageView
.draw()
.then(() => {
if (this._mounted) {
this.setState({ height: this.pdfPageView.viewport.height });
}
})
.catch(e => e);
});
}
}
 
render() {
const style = { height: 1100 };
if (this.state && this.state.height) {
style.height = this.state.height + 20;
}
return (
<div
id={`page-${this.props.page}`}
className="pdf-page"
ref={ref => {
this.pageContainer = ref;
}}
style={style}
>
{this.renderReferences()}
</div>
);
}
}
 
PDFPage.defaultProps = {
getViewportContainer: () => (isClient ? document.querySelector('.document-viewer') : null),
onVisible: () => {},
onHidden: () => {},
highlightReference: () => {},
};
 
PDFPage.propTypes = {
getViewportContainer: PropTypes.func,
page: PropTypes.number.isRequired,
onVisible: PropTypes.func,
onHidden: PropTypes.func,
onLoading: PropTypes.func.isRequired,
onUnload: PropTypes.func.isRequired,
Prop type "object" is forbidden
pdf: PropTypes.object.isRequired,
highlightReference: PropTypes.func,
containerWidth: PropTypes.number.isRequired,
};
 
Prefer named exports.
export default PDFPage;