aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryipstanley <stanley_yip@brown.edu>2019-06-19 14:25:47 -0400
committeryipstanley <stanley_yip@brown.edu>2019-06-19 14:25:47 -0400
commit46d57bc21cda4703855b85a4603bd471975d845b (patch)
treee27f30762e0b453521685127820dcfe50954afc4
parentc056adeca11f35972b5f75c6b1cc31292d5765d4 (diff)
deleting annotations
-rw-r--r--src/client/views/pdf/PDFMenu.tsx40
-rw-r--r--src/client/views/pdf/PDFViewer.tsx74
-rw-r--r--src/client/views/pdf/Page.tsx1
3 files changed, 97 insertions, 18 deletions
diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx
index 2462a5f94..5dd7b4bcd 100644
--- a/src/client/views/pdf/PDFMenu.tsx
+++ b/src/client/views/pdf/PDFMenu.tsx
@@ -19,9 +19,11 @@ export default class PDFMenu extends React.Component {
StartDrag: (e: PointerEvent) => void = emptyFunction;
Highlight: (d: Doc | undefined, color: string | undefined) => void = emptyFunction;
- @observable Highlighting: boolean = false;
+ Delete: () => void = emptyFunction;
+
+ @observable public Highlighting: boolean = false;
+ @observable public Status: "pdf" | "annotation" | "" = "";
- private _timeout: NodeJS.Timeout | undefined;
private _offsetY: number = 0;
private _offsetX: number = 0;
private _mainCont: React.RefObject<HTMLDivElement>;
@@ -66,8 +68,8 @@ export default class PDFMenu extends React.Component {
}
@action
- jumpTo = (x: number, y: number) => {
- if (!this._pinned) {
+ jumpTo = (x: number, y: number, forceJump: boolean = false) => {
+ if (!this._pinned || forceJump) {
this._transition = this._transitionDelay = "";
this._opacity = 1;
this._left = x;
@@ -159,11 +161,35 @@ export default class PDFMenu extends React.Component {
}
}
+ deleteClicked = (e: React.PointerEvent) => {
+ this.Delete();
+ }
+
+ handleContextMenu = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ e.preventDefault();
+ }
+
render() {
+ let buttons = this.Status === "pdf" ? [
+ <button className="pdfMenu-button" title="Click to Highlight" onClick={this.highlightClicked}
+ style={this.Highlighting ? { backgroundColor: "#121212" } : {}}>
+ <FontAwesomeIcon icon="highlighter" size="lg" style={{ transition: "transform 0.1s", transform: this.Highlighting ? "" : "rotate(-45deg)" }} />
+ </button>,
+ <button className="pdfMenu-button" title="Drag to Annotate" onPointerDown={this.pointerDown}><FontAwesomeIcon icon="comment-alt" size="lg" /></button>,
+ <button className="pdfMenu-button" title="Pin Menu" onClick={this.togglePin}
+ style={this._pinned ? { backgroundColor: "#121212" } : {}}>
+ <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transition: "transform 0.1s", transform: this._pinned ? "rotate(45deg)" : "" }} />
+ </button>
+ ] : [
+ <button className="pdfMenu-button" title="Delete Anchor" onPointerDown={this.deleteClicked}><FontAwesomeIcon icon="trash-alt" size="lg" /></button>
+ ];
+
return (
- <div className="pdfMenu-cont" onPointerLeave={this.pointerLeave} onPointerEnter={this.pointerEntered} ref={this._mainCont}
+ <div className="pdfMenu-cont" onPointerLeave={this.pointerLeave} onPointerEnter={this.pointerEntered} ref={this._mainCont} onContextMenu={this.handleContextMenu}
style={{ left: this._left, top: this._top, opacity: this._opacity, transition: this._transition, transitionDelay: this._transitionDelay }}>
- <button className="pdfMenu-button" title="Highlight" onClick={this.highlightClicked}
+ {buttons}
+ {/* <button className="pdfMenu-button" title="Highlight" onClick={this.highlightClicked}
style={this.Highlighting ? { backgroundColor: "#121212" } : {}}>
<FontAwesomeIcon icon="highlighter" size="lg" style={{ transition: "transform 0.1s", transform: this.Highlighting ? "" : "rotate(-45deg)" }} />
</button>
@@ -171,7 +197,7 @@ export default class PDFMenu extends React.Component {
<button className="pdfMenu-button" title="Pin Menu" onClick={this.togglePin}
style={this._pinned ? { backgroundColor: "#121212" } : {}}>
<FontAwesomeIcon icon="thumbtack" size="lg" style={{ transition: "transform 0.1s", transform: this._pinned ? "rotate(45deg)" : "" }} />
- </button>
+ </button> */}
<div className="pdfMenu-dragger" onPointerDown={this.dragStart} style={{ width: this._pinned ? "20px" : "0px" }} />
</div >
);
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index f0e55705d..ea4c0bca2 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -7,7 +7,7 @@ import { Dictionary } from "typescript-collections";
import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../new_fields/Doc";
import { Id } from "../../../new_fields/FieldSymbols";
import { List } from "../../../new_fields/List";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { BoolCast, Cast, NumCast, StrCast, FieldValue } from "../../../new_fields/Types";
import { emptyFunction } from "../../../Utils";
import { DocServer } from "../../DocServer";
import { Docs, DocUtils } from "../../documents/Documents";
@@ -138,6 +138,7 @@ class Viewer extends React.Component<IViewerProps> {
makeAnnotationDocument = (sourceDoc: Doc | undefined, s: number, color: string): Doc => {
let annoDocs: Doc[] = [];
+ let mainAnnoDoc = new Doc();
this._savedAnnotations.forEach((key: number, value: HTMLDivElement[]) => {
for (let anno of value) {
let annoDoc = new Doc();
@@ -147,6 +148,7 @@ class Viewer extends React.Component<IViewerProps> {
if (anno.style.width) annoDoc.width = parseInt(anno.style.width) / scale;
annoDoc.page = key;
annoDoc.target = sourceDoc;
+ annoDoc.group = mainAnnoDoc;
annoDoc.color = color;
annoDoc.type = AnnotationTypes.Region;
annoDocs.push(annoDoc);
@@ -154,13 +156,12 @@ class Viewer extends React.Component<IViewerProps> {
}
});
- let annoDoc = new Doc();
- annoDoc.annotations = new List<Doc>(annoDocs);
+ mainAnnoDoc.annotations = new List<Doc>(annoDocs);
if (sourceDoc) {
- DocUtils.MakeLink(sourceDoc, annoDoc, undefined, `Annotation from ${StrCast(this.props.parent.Document.title)}`, "", StrCast(this.props.parent.Document.title));
+ DocUtils.MakeLink(sourceDoc, mainAnnoDoc, undefined, `Annotation from ${StrCast(this.props.parent.Document.title)}`, "", StrCast(this.props.parent.Document.title));
}
this._savedAnnotations.clear();
- return annoDoc;
+ return mainAnnoDoc;
}
drop = async (e: Event, de: DragManager.DropEvent) => {
@@ -508,6 +509,57 @@ interface IAnnotationProps {
class RegionAnnotation extends React.Component<IAnnotationProps> {
@observable private _backgroundColor: string = "red";
+ private _reactionDisposer?: IReactionDisposer;
+ private _mainCont: React.RefObject<HTMLDivElement>;
+
+ constructor(props: IAnnotationProps) {
+ super(props);
+
+ this._mainCont = React.createRef();
+ }
+
+ componentDidMount() {
+ this._reactionDisposer = reaction(
+ () => BoolCast(this.props.document.delete),
+ () => {
+ if (BoolCast(this.props.document.delete)) {
+ if (this._mainCont.current) {
+ this._mainCont.current.style.display = "none";
+ }
+ }
+ },
+ { fireImmediately: true }
+ );
+ }
+
+ componentWillUnmount() {
+ this._reactionDisposer && this._reactionDisposer();
+ }
+
+ deleteAnnotation = () => {
+ let annotation = DocListCast(this.props.parent.props.parent.Document.annotations);
+ let group = FieldValue(Cast(this.props.document.group, Doc));
+ if (group && annotation.indexOf(group) !== -1) {
+ let newAnnotations = annotation.filter(a => a !== FieldValue(Cast(this.props.document.group, Doc)));
+ this.props.parent.props.parent.Document.annotations = new List<Doc>(newAnnotations);
+ }
+
+ if (group) {
+ let groupAnnotations = DocListCast(group.annotations);
+ groupAnnotations.forEach(anno => anno.delete = true);
+ }
+ }
+
+
+ // annotateThis = (e: PointerEvent) => {
+ // e.preventDefault();
+ // e.stopPropagation();
+ // // document that this annotation is linked to
+ // let targetDoc = Docs.TextDocument({ width: 200, height: 200, title: "New Annotation" });
+ // let group = FieldValue(Cast(this.props.document.group, Doc));
+ // }
+
+ @action
onPointerDown = (e: React.PointerEvent) => {
if (e.button === 0) {
let targetDoc = Cast(this.props.document.target, Doc, null);
@@ -515,16 +567,16 @@ class RegionAnnotation extends React.Component<IAnnotationProps> {
DocumentManager.Instance.jumpToDocument(targetDoc);
}
}
- // if (e.button === 2) {
- // console.log("right");
- // e.stopPropagation();
- // e.preventDefault();
- // }
+ if (e.button === 2) {
+ PDFMenu.Instance.Status = "annotation";
+ PDFMenu.Instance.Delete = this.deleteAnnotation;
+ PDFMenu.Instance.jumpTo(e.clientX, e.clientY, true);
+ }
}
render() {
return (
- <div className="pdfViewer-annotationBox" onPointerDown={this.onPointerDown}
+ <div className="pdfViewer-annotationBox" onPointerDown={this.onPointerDown} ref={this._mainCont}
style={{ top: this.props.y * scale, left: this.props.x * scale, width: this.props.width * scale, height: this.props.height * scale, pointerEvents: "all", backgroundColor: StrCast(this.props.document.color) }}></div>
);
}
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
index 39e737c32..734dff7fc 100644
--- a/src/client/views/pdf/Page.tsx
+++ b/src/client/views/pdf/Page.tsx
@@ -191,6 +191,7 @@ export default class Page extends React.Component<IPageProps> {
else if (e.button === 0) {
PDFMenu.Instance.StartDrag = this.startDrag;
PDFMenu.Instance.Highlight = this.highlight;
+ PDFMenu.Instance.Status = "pdf";
PDFMenu.Instance.fadeOut(true);
let target: any = e.target;
if (target && target.parentElement === this._textLayer.current) {