diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/pdf/PDFViewer.tsx | 76 | ||||
-rw-r--r-- | src/client/views/pdf/Page.tsx | 67 |
2 files changed, 39 insertions, 104 deletions
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index deacdd623..e54dfea6f 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -278,7 +278,9 @@ class Viewer extends React.Component<IViewerProps> { parent={this.props.parent} renderAnnotations={this.renderAnnotations} makePin={this.createPinAnnotation} + createAnnotation={this.createAnnotation} sendAnnotations={this.receiveAnnotations} + makeAnnotationDocuments={this.makeAnnotationDocuments} receiveAnnotations={this.sendAnnotations} {...this.props} /> )); @@ -318,7 +320,9 @@ class Viewer extends React.Component<IViewerProps> { parent={this.props.parent} makePin={this.createPinAnnotation} renderAnnotations={this.renderAnnotations} + createAnnotation={this.createAnnotation} sendAnnotations={this.receiveAnnotations} + makeAnnotationDocuments={this.makeAnnotationDocuments} receiveAnnotations={this.sendAnnotations} {...this.props} /> ); @@ -334,7 +338,13 @@ class Viewer extends React.Component<IViewerProps> { @action receiveAnnotations = (annotations: HTMLDivElement[], page: number) => { - this._savedAnnotations.setValue(page, annotations); + if (page === -1) { + this._savedAnnotations.values().forEach(v => v.forEach(a => a.remove())); + this._savedAnnotations.keys().forEach(k => this._savedAnnotations.setValue(k, annotations)); + } + else { + this._savedAnnotations.setValue(page, annotations); + } } sendAnnotations = (page: number): HTMLDivElement[] | undefined => { @@ -346,7 +356,7 @@ class Viewer extends React.Component<IViewerProps> { let pinAnno = new Doc(); pinAnno.x = x; - pinAnno.y = y; + pinAnno.y = y + this.getPageHeight(page); pinAnno.width = pinAnno.height = PinRadius; pinAnno.page = page; pinAnno.target = targetDoc; @@ -362,12 +372,6 @@ class Viewer extends React.Component<IViewerProps> { else { this.props.parent.Document.annotations = new List<Doc>([annoDoc]); } - // let pinAnno = document.createElement("div"); - // pinAnno.className = "pdfViewer-pinAnnotation"; - // pinAnno.style.top = (y - (radius / 2)).toString(); - // pinAnno.style.left = (x - (radius / 2)).toString(); - // pinAnno.style.height = pinAnno.style.width = radius.toString(); - // if (this._annotationLayer.current) this._annotationLayer.current.append(pinAnno); } // get the page index that the vertical offset passed in is on @@ -404,10 +408,7 @@ class Viewer extends React.Component<IViewerProps> { <div key={`pdfviewer-placeholder-${i}`} className="pdfviewer-placeholder" style={{ width: this._pageSizes[i] ? this._pageSizes[i].width : 0, height: this._pageSizes[i] ? this._pageSizes[i].height : 0 }} /> )); this._visibleElements = new Array<JSX.Element>(...divs); - // On load, render pdf - // setTimeout(() => { this.renderPages(this.startIndex, this.endIndex, true); - // }, 1000); } } @@ -423,15 +424,32 @@ class Viewer extends React.Component<IViewerProps> { return counter; } + createAnnotation = (div: HTMLDivElement, page: number) => { + if (this._annotationLayer.current) { + if (div.style.top) { + div.style.top = (parseInt(div.style.top) + this.getPageHeight(page)).toString(); + } + this._annotationLayer.current.append(div); + let savedPage = this._savedAnnotations.getValue(page); + if (savedPage) { + savedPage.push(div); + this._savedAnnotations.setValue(page, savedPage); + } + else { + this._savedAnnotations.setValue(page, [div]); + } + } + } + renderAnnotation = (anno: Doc): JSX.Element[] => { let annotationDocs = DocListCast(anno.annotations); let res = annotationDocs.map(a => { let type = NumCast(a.type); switch (type) { case AnnotationTypes.Pin: - return <PinAnnotation parent={this} document={a} x={NumCast(a.x)} y={NumCast(a.y) + this.getPageHeight(NumCast(a.page))} width={a[WidthSym]()} height={a[HeightSym]()} key={a[Id]} />; + return <PinAnnotation parent={this} document={a} x={NumCast(a.x)} y={NumCast(a.y)} width={a[WidthSym]()} height={a[HeightSym]()} key={a[Id]} />; case AnnotationTypes.Region: - return <RegionAnnotation parent={this} document={a} x={NumCast(a.x)} y={NumCast(a.y) + this.getPageHeight(NumCast(a.page))} width={a[WidthSym]()} height={a[HeightSym]()} key={a[Id]} />; + return <RegionAnnotation parent={this} document={a} x={NumCast(a.x)} y={NumCast(a.y)} width={a[WidthSym]()} height={a[HeightSym]()} key={a[Id]} />; default: return <div></div>; } @@ -439,18 +457,6 @@ class Viewer extends React.Component<IViewerProps> { return res; } - // ScreenToLocalTransform = (): Transform => { - // if (this._annotationLayer.current) { - // let boundingRect = this._annotationLayer.current.getBoundingClientRect(); - // let x = boundingRect.left; - // let y = boundingRect.top; - // let scale = NumCast(this.props.parent.Document.nativeWidth) / boundingRect.width; - // let t = new Transform(x, y, scale); - // return t; - // } - // return Transform.Identity(); - // } - render() { trace(); return ( @@ -458,8 +464,8 @@ class Viewer extends React.Component<IViewerProps> { <div className="viewer"> {this._visibleElements} </div> - <div className="pdfViewer-annotationLayer" ref={this._annotationLayer} style={{ height: this.props.parent.Document.nativeHeight, width: `100%`, pointerEvents: this._pointerEvents }}> - <div className="pdfViewer-annotationLayer-subCont" style={{ transform: `translateY(${-this.scrollY}px)` }}> + <div className="pdfViewer-annotationLayer" style={{ height: this.props.parent.Document.nativeHeight, width: `100%`, pointerEvents: this._pointerEvents }}> + <div className="pdfViewer-annotationLayer-subCont" style={{ transform: `translateY(${-this.scrollY}px)` }} ref={this._annotationLayer}> {this._annotations.map(anno => this.renderAnnotation(anno))} </div> </div> @@ -542,26 +548,10 @@ class PinAnnotation extends React.Component<IAnnotationProps> { class RegionAnnotation extends React.Component<IAnnotationProps> { @observable private _backgroundColor: string = "red"; - // private _reactionDisposer?: IReactionDisposer; - - constructor(props: IAnnotationProps) { - super(props); - - // this._reactionDisposer = reaction( - // () => { BoolCast(this.props.document.selected); }, - // () => { this._backgroundColor = BoolCast(this.props.document.selected) ? "yellow" : "red"; }, - // { fireImmediately: true } - // ) - } - onPointerDown = (e: React.PointerEvent) => { let targetDoc = Cast(this.props.document.target, Doc, null); if (targetDoc) { DocumentManager.Instance.jumpToDocument(targetDoc); - // let annotations = DocListCast(targetDoc.proto!.linkedFromDocs); - // if (annotations && annotations.length) { - // annotations.forEach(anno => anno.selected = true); - // } } } diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx index 998ac25fd..9e3bf4954 100644 --- a/src/client/views/pdf/Page.tsx +++ b/src/client/views/pdf/Page.tsx @@ -26,6 +26,8 @@ interface IPageProps { makePin: (x: number, y: number, page: number) => void; sendAnnotations: (annotations: HTMLDivElement[], page: number) => void; receiveAnnotations: (page: number) => HTMLDivElement[] | undefined; + createAnnotation: (div: HTMLDivElement, page: number) => void; + makeAnnotationDocuments: (doc: Doc) => Doc; } @observer @@ -46,7 +48,6 @@ export default class Page extends React.Component<IPageProps> { private _annotationLayer: React.RefObject<HTMLDivElement>; private _marquee: React.RefObject<HTMLDivElement>; private _curly: React.RefObject<HTMLImageElement>; - private _currentAnnotations: HTMLDivElement[] = []; private _marqueeing: boolean = false; private _dragging: boolean = false; private _reactionDisposer?: IReactionDisposer; @@ -64,18 +65,9 @@ export default class Page extends React.Component<IPageProps> { if (this.props.pdf) { this.update(this.props.pdf); } - - let received = this.props.receiveAnnotations(this.props.page); - this._currentAnnotations = received ? received : []; - if (this._annotationLayer.current) { - this._annotationLayer.current.append(...this._currentAnnotations); - } } componentWillUnmount = (): void => { - console.log(this._currentAnnotations); - this.props.sendAnnotations(this._currentAnnotations, this.props.page); - if (this._reactionDisposer) { this._reactionDisposer(); } @@ -140,33 +132,6 @@ export default class Page extends React.Component<IPageProps> { } /** - * @param targetDoc: Document that annotations are linked to - * This method makes the list of current annotations into documents linked to - * the parameter passed in. - */ - makeAnnotationDocuments = (targetDoc: Doc): Doc => { - let annoDocs: Doc[] = []; - - for (let anno of this._currentAnnotations) { - let annoDoc = new Doc(); - annoDoc.x = anno.offsetLeft; - annoDoc.y = anno.offsetTop; - annoDoc.height = anno.offsetHeight; - annoDoc.width = anno.offsetWidth; - annoDoc.page = this.props.page; - annoDoc.target = targetDoc; - annoDoc.type = AnnotationTypes.Region; - annoDocs.push(annoDoc); - anno.remove(); - } - let annoDoc = new Doc(); - annoDoc.annotations = new List<Doc>(annoDocs); - DocUtils.MakeLink(annoDoc, targetDoc, undefined, `Annotation from ${StrCast(this.props.parent.Document.title)}`, "", StrCast(this.props.parent.Document.title)); - this._currentAnnotations = []; - return annoDoc; - } - - /** * This is temporary for creating annotations from highlights. It will * start a drag event and create or put the necessary info into the drag event. */ @@ -184,7 +149,7 @@ export default class Page extends React.Component<IPageProps> { let targetDoc = Docs.TextDocument({ width: 200, height: 200, title: "New Annotation" }); targetDoc.targetPage = this.props.page; // creates annotation documents for current highlights - let annotationDoc = this.makeAnnotationDocuments(targetDoc); + let annotationDoc = this.props.makeAnnotationDocuments(targetDoc); let targetAnnotations = DocListCast(this.props.parent.Document.annotations); if (targetAnnotations) { targetAnnotations.push(annotationDoc); @@ -246,10 +211,7 @@ export default class Page extends React.Component<IPageProps> { document.removeEventListener("pointerup", this.onSelectEnd); document.addEventListener("pointerup", this.onSelectEnd); if (!e.ctrlKey) { - for (let anno of this._currentAnnotations) { - anno.remove(); - } - this._currentAnnotations = []; + this.props.sendAnnotations([], -1); } } } @@ -336,10 +298,7 @@ export default class Page extends React.Component<IPageProps> { copy.style.opacity = this._marquee.current.style.opacity; } copy.className = this._marquee.current.className; - if (this._annotationLayer.current) { - this._annotationLayer.current.append(copy); - this._currentAnnotations.push(copy); - } + this.props.createAnnotation(copy, this.props.page); this._marquee.current.style.opacity = "0"; } @@ -362,8 +321,7 @@ export default class Page extends React.Component<IPageProps> { annoBox.style.left = ((rect.left - boundingRect.left) * (this._textLayer.current.offsetWidth / boundingRect.width)).toString(); annoBox.style.width = (rect.width * this._textLayer.current.offsetWidth / boundingRect.width).toString(); annoBox.style.height = (rect.height * this._textLayer.current.offsetHeight / boundingRect.height).toString(); - if (this._annotationLayer.current) this._annotationLayer.current.append(annoBox); - this._currentAnnotations.push(annoBox); + this.props.createAnnotation(annoBox, this.props.page); } } } @@ -395,19 +353,6 @@ export default class Page extends React.Component<IPageProps> { } } - renderAnnotation = (anno: Doc | undefined): HTMLDivElement => { - let annoBox = document.createElement("div"); - if (anno) { - annoBox.className = "pdfViewer-annotationBox"; - // transforms the positions from screen onto the pdf div - annoBox.style.top = NumCast(anno.x).toString(); - annoBox.style.left = NumCast(anno.y).toString(); - annoBox.style.width = NumCast(anno.width).toString(); - annoBox.style.height = NumCast(anno.height).toString() - } - return annoBox; - } - render() { return ( <div onPointerDown={this.onPointerDown} onDoubleClick={this.doubleClick} className={this.props.name} style={{ "width": this._width, "height": this._height }}> |