aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/pdf
diff options
context:
space:
mode:
authorTyler Schicke <tyler_schicke@brown.edu>2019-07-15 09:48:15 -0400
committerTyler Schicke <tyler_schicke@brown.edu>2019-07-15 09:48:15 -0400
commit47bd101ae6d57f7de0fb2ceac2c9b2f014ea9b82 (patch)
treea624cfe2e0a2f5c5806c81b5ee9f761621f74961 /src/client/views/pdf
parent7e423358d420d81ba2fa551195a296f54152bd6c (diff)
parente68ec039021022f8e8c55ff560db848066b81724 (diff)
Merge branch 'master' of github-tsch-brown:browngraphicslab/Dash-Web
Diffstat (limited to 'src/client/views/pdf')
-rw-r--r--src/client/views/pdf/PDFMenu.scss4
-rw-r--r--src/client/views/pdf/PDFMenu.tsx14
-rw-r--r--src/client/views/pdf/PDFViewer.tsx7
-rw-r--r--src/client/views/pdf/Page.tsx34
4 files changed, 38 insertions, 21 deletions
diff --git a/src/client/views/pdf/PDFMenu.scss b/src/client/views/pdf/PDFMenu.scss
index a4624b1f6..b06d19c53 100644
--- a/src/client/views/pdf/PDFMenu.scss
+++ b/src/client/views/pdf/PDFMenu.scss
@@ -21,6 +21,10 @@
.pdfMenu-dragger {
height: 100%;
transition: width .2s;
+ background-image: url("https://logodix.com/logo/1020374.png");
+ background-size: 90% 100%;
+ background-repeat: no-repeat;
+ background-position: left center;
}
.pdfMenu-addTag {
diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx
index feaa1f652..27c2a8f1a 100644
--- a/src/client/views/pdf/PDFMenu.tsx
+++ b/src/client/views/pdf/PDFMenu.tsx
@@ -18,7 +18,7 @@ export default class PDFMenu extends React.Component {
@observable private _transitionDelay: string = "";
- StartDrag: (e: PointerEvent, ele: HTMLDivElement) => void = emptyFunction;
+ StartDrag: (e: PointerEvent, ele: HTMLElement) => void = emptyFunction;
Highlight: (d: Doc | undefined, color: string | undefined) => void = emptyFunction;
Delete: () => void = emptyFunction;
Snippet: (marquee: { left: number, top: number, width: number, height: number }) => void = emptyFunction;
@@ -34,7 +34,7 @@ export default class PDFMenu extends React.Component {
private _offsetY: number = 0;
private _offsetX: number = 0;
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
- private _commentCont: React.RefObject<HTMLDivElement> = React.createRef();
+ private _commentCont = React.createRef<HTMLButtonElement>();
private _snippetButton: React.RefObject<HTMLButtonElement> = React.createRef();
private _dragging: boolean = false;
@observable private _keyValue: string = "";
@@ -238,24 +238,24 @@ export default class PDFMenu extends React.Component {
render() {
let buttons = this.Status === "pdf" || this.Status === "snippet" ? [
- <button className="pdfMenu-button" title="Click to Highlight" onClick={this.highlightClicked} key="1"
+ <button key="1" 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" ref={this._commentCont} onPointerDown={this.pointerDown}><FontAwesomeIcon icon="comment-alt" size="lg" key="2" /></button>,
this.Status === "snippet" ? <button className="pdfMenu-button" title="Drag to Snippetize Selection" onPointerDown={this.snippetStart} ref={this._snippetButton}><FontAwesomeIcon icon="cut" size="lg" /></button> : undefined,
- <button className="pdfMenu-button" title="Pin Menu" onClick={this.togglePin} key="3"
+ <button key="3" 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" key="1" /></button>,
- <button className="pdfMenu-button" title="Pin to Presentation" onPointerDown={this.PinToPres}><FontAwesomeIcon icon="map-pin" size="lg" key="2" /></button>,
+ <button key="4" className="pdfMenu-button" title="Delete Anchor" onPointerDown={this.deleteClicked}><FontAwesomeIcon icon="trash-alt" size="lg" key="1" /></button>,
+ <button key="5" className="pdfMenu-button" title="Pin to Presentation" onPointerDown={this.PinToPres}><FontAwesomeIcon icon="map-pin" size="lg" key="2" /></button>,
<div className="pdfMenu-addTag" key="3">
<input onKeyDown={handleBackspace} onChange={this.keyChanged} placeholder="Key" style={{ gridColumn: 1 }} />
<input onKeyDown={handleBackspace} onChange={this.valueChanged} placeholder="Value" style={{ gridColumn: 3 }} />
</div>,
- <button className="pdfMenu-button" title={`Add tag: ${this._keyValue} with value: ${this._valueValue}`} onPointerDown={this.addTag}><FontAwesomeIcon style={{ transition: "all .2s" }} color={this._added ? "#42f560" : "white"} icon="check" size="lg" key="4" /></button>,
+ <button key="6" className="pdfMenu-button" title={`Add tag: ${this._keyValue} with value: ${this._valueValue}`} onPointerDown={this.addTag}><FontAwesomeIcon style={{ transition: "all .2s" }} color={this._added ? "#42f560" : "white"} icon="check" size="lg" key="4" /></button>,
];
return (
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 8f5a356c8..01fd1c247 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -236,12 +236,13 @@ export class Viewer extends React.Component<IViewerProps> {
}
}
+ @action
makeAnnotationDocument = (sourceDoc: Doc | undefined, s: number, color: string): Doc => {
let annoDocs: Doc[] = [];
let mainAnnoDoc = Docs.Create.InstanceFromProto(new Doc(), "", {});
mainAnnoDoc.title = "Annotation on " + StrCast(this.props.parent.Document.title);
- mainAnnoDoc.pdfDoc = this.props.parent.Document;
+ mainAnnoDoc.pdfDoc = this.props.parent.props.Document;
let minY = Number.MAX_VALUE;
this._savedAnnotations.forEach((key: number, value: HTMLDivElement[]) => {
for (let anno of value) {
@@ -449,10 +450,6 @@ export class Viewer extends React.Component<IViewerProps> {
@action
search = (searchString: string) => {
- if (searchString.length === 0) {
- return;
- }
-
if (this._pdfViewer._pageViewsReady) {
this._pdfFindController.executeCommand('find',
{
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
index 5ff39c867..3d8973414 100644
--- a/src/client/views/pdf/Page.tsx
+++ b/src/client/views/pdf/Page.tsx
@@ -2,7 +2,7 @@ import { observer } from "mobx-react";
import React = require("react");
import { observable, action, runInAction, IReactionDisposer, reaction } from "mobx";
import * as Pdfjs from "pdfjs-dist";
-import { Opt, Doc, FieldResult, Field, DocListCast, WidthSym, HeightSym } from "../../../new_fields/Doc";
+import { Opt, Doc, FieldResult, Field, DocListCast, WidthSym, HeightSym, DocListCastAsync } from "../../../new_fields/Doc";
import "./PDFViewer.scss";
import "pdfjs-dist/web/pdf_viewer.css";
import { PDFBox } from "../nodes/PDFBox";
@@ -10,7 +10,7 @@ import { DragManager } from "../../util/DragManager";
import { Docs, DocUtils } from "../../documents/Documents";
import { List } from "../../../new_fields/List";
import { emptyFunction } from "../../../Utils";
-import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
import { listSpec } from "../../../new_fields/Schema";
import { menuBar } from "prosemirror-menu";
import { AnnotationTypes, PDFViewer, scale } from "./PDFViewer";
@@ -55,6 +55,8 @@ export default class Page extends React.Component<IPageProps> {
// private _curly: React.RefObject<HTMLImageElement>;
private _marqueeing: boolean = false;
private _reactionDisposer?: IReactionDisposer;
+ private _startY: number = 0;
+ private _startX: number = 0;
constructor(props: IPageProps) {
super(props);
@@ -152,20 +154,30 @@ export default class Page extends React.Component<IPageProps> {
* start a drag event and create or put the necessary info into the drag event.
*/
@action
- startDrag = (e: PointerEvent, ele: HTMLDivElement): void => {
+ startDrag = (e: PointerEvent, ele: HTMLElement): void => {
e.preventDefault();
e.stopPropagation();
let thisDoc = this.props.parent.Document;
// document that this annotation is linked to
let targetDoc = Docs.Create.TextDocument({ width: 200, height: 200, title: "New Annotation" });
targetDoc.targetPage = this.props.page;
- let annotationDoc = this.highlight(targetDoc, "red");
+ let annotationDoc = this.highlight(undefined, "red");
+ annotationDoc.linkedToDoc = false;
// create dragData and star tdrag
let dragData = new DragManager.AnnotationDragData(thisDoc, annotationDoc, targetDoc);
if (this._textLayer.current) {
DragManager.StartAnnotationDrag([ele], dragData, e.pageX, e.pageY, {
handlers: {
- dragComplete: emptyFunction,
+ dragComplete: async () => {
+ if (!(await annotationDoc.linkedToDoc)) {
+ let annotations = await DocListCastAsync(annotationDoc.annotations);
+ if (annotations) {
+ annotations.forEach(anno => {
+ anno.target = targetDoc;
+ });
+ }
+ }
+ }
},
hideSource: false
});
@@ -220,8 +232,8 @@ export default class Page extends React.Component<IPageProps> {
let current = this._textLayer.current;
if (current) {
let boundingRect = current.getBoundingClientRect();
- this._marqueeX = (e.clientX - boundingRect.left) * (current.offsetWidth / boundingRect.width);
- this._marqueeY = (e.clientY - boundingRect.top) * (current.offsetHeight / boundingRect.height);
+ this._startX = this._marqueeX = (e.clientX - boundingRect.left) * (current.offsetWidth / boundingRect.width);
+ this._startY = this._marqueeY = (e.clientY - boundingRect.top) * (current.offsetHeight / boundingRect.height);
}
this._marqueeing = true;
if (this._marquee.current) this._marquee.current.style.opacity = "0.2";
@@ -244,8 +256,12 @@ export default class Page extends React.Component<IPageProps> {
if (current) {
// transform positions and find the width and height to set the marquee to
let boundingRect = current.getBoundingClientRect();
- this._marqueeWidth = (e.clientX - boundingRect.left) * (current.offsetWidth / boundingRect.width) - this._marqueeX;
- this._marqueeHeight = (e.clientY - boundingRect.top) * (current.offsetHeight / boundingRect.height) - this._marqueeY;
+ this._marqueeWidth = ((e.clientX - boundingRect.left) * (current.offsetWidth / boundingRect.width)) - this._startX;
+ this._marqueeHeight = ((e.clientY - boundingRect.top) * (current.offsetHeight / boundingRect.height)) - this._startY;
+ this._marqueeX = Math.min(this._startX, this._startX + this._marqueeWidth);
+ this._marqueeY = Math.min(this._startY, this._startY + this._marqueeHeight);
+ this._marqueeWidth = Math.abs(this._marqueeWidth);
+ this._marqueeHeight = Math.abs(this._marqueeHeight);
let { background, opacity, transform: transform } = this.getCurlyTransform();
if (this._marquee.current /*&& this._curly.current*/) {
this._marquee.current.style.background = background;