From 64f6a0d54656ded133af113746003d61eaa1d651 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Tue, 11 Jun 2019 15:04:47 -0400 Subject: pin annotations base --- src/client/views/pdf/PDFViewer.scss | 6 ++++ src/client/views/pdf/PDFViewer.tsx | 72 +++++++++++++++++++++++++++++++++++-- src/client/views/pdf/Page.tsx | 22 ++++++++++-- 3 files changed, 96 insertions(+), 4 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss index 831e6add1..57be04b93 100644 --- a/src/client/views/pdf/PDFViewer.scss +++ b/src/client/views/pdf/PDFViewer.scss @@ -34,4 +34,10 @@ position: absolute; top: 0; overflow: visible hidden; +} + +.pdfViewer-pinAnnotation { + background-color: red; + position: absolute; + border-radius: 100%; } \ No newline at end of file diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 092765324..bc773ebef 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -9,9 +9,11 @@ import { PDFBox } from "../nodes/PDFBox"; import Page from "./Page"; import { NumCast, Cast, BoolCast } from "../../../new_fields/Types"; import { Id } from "../../../new_fields/FieldSymbols"; -import { DocUtils } from "../../documents/Documents"; +import { DocUtils, Docs } from "../../documents/Documents"; import { DocumentManager } from "../../util/DocumentManager"; import { SelectionManager } from "../../util/SelectionManager"; +import { List } from "../../../new_fields/List"; +import { DocumentContentsView } from "../nodes/DocumentContentsView"; interface IPDFViewerProps { url: string; @@ -56,6 +58,8 @@ interface IViewerProps { url: string; } +const PinRadius = 25; + /** * Handles rendering and virtualization of the pdf */ @@ -193,6 +197,7 @@ class Viewer extends React.Component { pageLoaded={this.pageLoaded} parent={this.props.parent} renderAnnotations={this.renderAnnotations} + makePin={this.createPinAnnotation} {...this.props} /> )); let arr = Array.from(Array(numPages).keys()).map(() => false); @@ -229,6 +234,7 @@ class Viewer extends React.Component { name={`${this.props.pdf ? this.props.pdf.fingerprint + `-page${i + 1}` : "undefined"}`} pageLoaded={this.pageLoaded} parent={this.props.parent} + makePin={this.createPinAnnotation} renderAnnotations={this.renderAnnotations} {...this.props} /> ); @@ -242,6 +248,33 @@ class Viewer extends React.Component { return; } + createPinAnnotation = (x: number, y: number): void => { + let targetDoc = Docs.TextDocument({ title: "New Pin Annotation" }); + + let pinAnno = new Doc(); + pinAnno.x = x; + pinAnno.y = y; + pinAnno.width = pinAnno.height = PinRadius; + pinAnno.page = this.getIndex(y); + pinAnno.target = targetDoc; + pinAnno.type = AnnotationTypes.Pin; + // this._annotations.push(pinAnno); + let annotations = DocListCast(this.props.parent.Document.annotations); + if (annotations && annotations.length) { + annotations.push(pinAnno); + this.props.parent.Document.annotations = new List(annotations); + } + else { + this.props.parent.Document.annotations = new List([pinAnno]); + } + // 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 getIndex = (vOffset: number) => { if (this._loaded) { @@ -295,6 +328,18 @@ class Viewer extends React.Component { return counter; } + renderAnnotation = (anno: Doc): JSX.Element => { + let type = NumCast(anno.type); + switch (type) { + case AnnotationTypes.Pin: + return ; + case AnnotationTypes.Region: + return ; + default: + return
; + } + } + render() { return (
@@ -303,7 +348,7 @@ class Viewer extends React.Component {
- {this._annotations.map(anno => )} + {this._annotations.map(anno => this.renderAnnotation(anno))}
@@ -311,6 +356,10 @@ class Viewer extends React.Component { } } +export enum AnnotationTypes { + Region, Pin +} + interface IAnnotationProps { x: number; y: number; @@ -319,6 +368,25 @@ interface IAnnotationProps { document: Doc; } +class PinAnnotation extends React.Component { + @observable private _backgroundColor: string = "red"; + + pointerDown = (e: React.PointerEvent) => { + + } + + render() { + let targetDoc = Cast(this.props.document.targetDoc, Doc, Docs.TextDocument({ title: "New Pin Annotation" })); + return ( +
+ {/* */} +
+ ); + } +} + class RegionAnnotation extends React.Component { @observable private _backgroundColor: string = "red"; diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx index 5738889c4..fe7369aeb 100644 --- a/src/client/views/pdf/Page.tsx +++ b/src/client/views/pdf/Page.tsx @@ -13,6 +13,7 @@ import { emptyFunction } from "../../../Utils"; import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; import { listSpec } from "../../../new_fields/Schema"; import { menuBar } from "prosemirror-menu"; +import { AnnotationTypes } from "./PDFViewer"; interface IPageProps { pdf: Opt; @@ -22,6 +23,7 @@ interface IPageProps { pageLoaded: (index: number, page: Pdfjs.PDFPageViewport) => void; parent: PDFBox; renderAnnotations: (annotations: Doc[], removeOld: boolean) => void; + makePin: (x: number, y: number) => void; } @observer @@ -142,6 +144,7 @@ export default class Page extends React.Component { annoDoc.width = anno.offsetWidth; annoDoc.page = this.props.page; annoDoc.target = targetDoc; + annoDoc.type = AnnotationTypes.Region; annoDocs.push(annoDoc); DocUtils.MakeLink(annoDoc, targetDoc, `Annotation from ${StrCast(this.props.parent.Document.title)}`, "", StrCast(this.props.parent.Document.title)); anno.remove(); @@ -169,7 +172,6 @@ export default class Page extends React.Component { targetDoc.targetPage = this.props.page; // creates annotation documents for current highlights let annotationDocs = this.makeAnnotationDocuments(targetDoc); - console.log(annotationDocs); let targetAnnotations = DocListCast(this.props.parent.Document.annotations); if (targetAnnotations) { targetAnnotations.push(...annotationDocs); @@ -364,6 +366,22 @@ export default class Page extends React.Component { document.removeEventListener("pointerup", this.onSelectEnd); } + doubleClick = (e: React.MouseEvent) => { + let target: any = e.target; + // if double clicking text + if (target && target.parentElement === this._textLayer.current) { + // do something to select the paragraph ideally + } + + let current = this._textLayer.current; + if (current) { + let boundingRect = current.getBoundingClientRect(); + let x = (e.clientX - boundingRect.left) * (current.offsetWidth / boundingRect.width); + let y = (e.clientY - boundingRect.top) * (current.offsetHeight / boundingRect.height); + this.props.makePin(x, y); + } + } + renderAnnotation = (anno: Doc | undefined): HTMLDivElement => { let annoBox = document.createElement("div"); if (anno) { @@ -379,7 +397,7 @@ export default class Page extends React.Component { render() { return ( -
+
-- cgit v1.2.3-70-g09d2