From e910a6cd56936234e451994c893d8592e430f828 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Tue, 25 Jun 2019 13:54:20 -0400 Subject: pdf view specs fixes/changes --- src/client/views/pdf/PDFMenu.scss | 7 ++++ src/client/views/pdf/PDFMenu.tsx | 55 ++++++++++++++++++++-------- src/client/views/pdf/PDFViewer.tsx | 75 +++++++++++++++++++++++++++----------- 3 files changed, 101 insertions(+), 36 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/pdf/PDFMenu.scss b/src/client/views/pdf/PDFMenu.scss index 22868082a..a4624b1f6 100644 --- a/src/client/views/pdf/PDFMenu.scss +++ b/src/client/views/pdf/PDFMenu.scss @@ -22,4 +22,11 @@ height: 100%; transition: width .2s; } + + .pdfMenu-addTag { + display: grid; + width: 200px; + padding: 5px; + grid-template-columns: 90px 20px 90px; + } } \ No newline at end of file diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx index a8e176858..e58ad9ccc 100644 --- a/src/client/views/pdf/PDFMenu.tsx +++ b/src/client/views/pdf/PDFMenu.tsx @@ -1,9 +1,9 @@ import React = require("react"); import "./PDFMenu.scss"; -import { observable, action } from "mobx"; +import { observable, action, runInAction } from "mobx"; import { observer } from "mobx-react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { emptyFunction } from "../../../Utils"; +import { emptyFunction, returnZero, returnTrue, returnFalse } from "../../../Utils"; import { Doc } from "../../../new_fields/Doc"; import { DragManager } from "../../util/DragManager"; import { DocUtils } from "../../documents/Documents"; @@ -23,6 +23,7 @@ export default class PDFMenu extends React.Component { Highlight: (d: Doc | undefined, color: string | undefined) => void = emptyFunction; Delete: () => void = emptyFunction; Snippet: (marquee: { left: number, top: number, width: number, height: number }) => void = emptyFunction; + AddTag: (key: string, value: string) => boolean = returnFalse; @observable public Highlighting: boolean = false; @observable public Status: "pdf" | "annotation" | "snippet" | "" = ""; @@ -35,6 +36,9 @@ export default class PDFMenu extends React.Component { private _mainCont: React.RefObject; private _dragging: boolean = false; private _snippetButton: React.RefObject; + @observable private _keyValue: string = ""; + @observable private _valueValue: string = ""; + @observable private _added: boolean = false;; constructor(props: Readonly<{}>) { super(props); @@ -209,35 +213,56 @@ export default class PDFMenu extends React.Component { e.preventDefault(); } + @action + keyChanged = (e: React.ChangeEvent) => { + this._keyValue = e.currentTarget.value; + } + + @action + valueChanged = (e: React.ChangeEvent) => { + this._valueValue = e.currentTarget.value; + } + + @action + addTag = (e: React.PointerEvent) => { + if (this._keyValue.length > 0 && this._valueValue.length > 0) { + this._added = this.AddTag(this._keyValue, this._valueValue); + + setTimeout( + () => { + runInAction(() => { + this._added = false; + }); + }, 1000 + ); + } + } + render() { let buttons = this.Status === "pdf" || this.Status === "snippet" ? [ - , - , + , this.Status === "snippet" ? : undefined, - ] : [ - + , +
+ + +
, + , ]; return (
{buttons} - {/* - - */}
); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 1eab13bc5..3df7dd77b 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -20,8 +20,8 @@ import "./PDFViewer.scss"; import React = require("react"); import PDFMenu from "./PDFMenu"; import { UndoManager } from "../../util/UndoManager"; -import { ScriptField } from "../../../fields/ScriptField"; import { CompileScript, CompiledScript, CompileResult } from "../../util/Scripting"; +import { ScriptField } from "../../../new_fields/ScriptField"; export const scale = 2; interface IPDFViewerProps { @@ -63,8 +63,6 @@ interface IViewerProps { url: string; } -const PinRadius = 25; - /** * Handles rendering and virtualization of the pdf */ @@ -85,14 +83,18 @@ class Viewer extends React.Component { private _annotationReactionDisposer?: IReactionDisposer; private _dropDisposer?: DragManager.DragDropDisposer; private _filterReactionDisposer?: IReactionDisposer; + private _viewer: React.RefObject; + private _mainCont: React.RefObject; + private _textContent: Pdfjs.TextContent[] = []; - @action - constructor(props: IViewerProps) { - super(props); + constructor(props: IViewerProps) { + super(props); - let scriptfield = Cast(this.props.parent.Document.filterScript, ScriptField); - this._script = scriptfield ? CompileScript(scriptfield.scriptString, { params: { this: Doc.name } }) : CompileScript("return true");; - } + let scriptfield = Cast(this.props.parent.Document.filterScript, ScriptField); + this._script = scriptfield ? scriptfield.script : CompileScript("return true"); + this._viewer = React.createRef(); + this._mainCont = React.createRef(); + } componentDidUpdate = (prevProps: IViewerProps) => { if (this.scrollY !== prevProps.scrollY) { @@ -118,21 +120,37 @@ class Viewer extends React.Component { if (this.props.parent.props.ContainingCollectionView) { this._filterReactionDisposer = reaction( - () => this.props.parent.Document.filterScript || this.props.parent.props.ContainingCollectionView!.props.Document.filterScript, + () => this.props.parent.Document.filterScript, () => { runInAction(() => { let scriptfield = Cast(this.props.parent.Document.filterScript, ScriptField); - this._script = scriptfield ? CompileScript(scriptfield.scriptString, { params: { this: Doc.name } }) : CompileScript("return true");; + this._script = scriptfield ? scriptfield.script : CompileScript("return true"); + if (this.props.parent.props.ContainingCollectionView) { + let ccvAnnos = DocListCast(this.props.parent.props.ContainingCollectionView.props.Document.annotations); + ccvAnnos.forEach(d => { + if (this._script && this._script.compiled) { + let run = this._script.run(d); + if (run.success) { + d.opacity = run.result ? 1 : 0; + } + } + }) + } }); } ); } + + if (this._mainCont.current) { + this._dropDisposer = this._mainCont.current && DragManager.MakeDropTarget(this._mainCont.current, { handlers: { drop: this.drop.bind(this) } }); + } } componentWillUnmount = () => { this._reactionDisposer && this._reactionDisposer(); this._annotationReactionDisposer && this._annotationReactionDisposer(); this._filterReactionDisposer && this._filterReactionDisposer(); + this._dropDisposer && this._dropDisposer(); } @action @@ -140,10 +158,14 @@ class Viewer extends React.Component { if (this._pageSizes.length === 0) { let pageSizes = Array<{ width: number, height: number }>(this.props.pdf.numPages); this._isPage = Array(this.props.pdf.numPages); + this._textContent = Array(this.props.pdf.numPages); for (let i = 0; i < this.props.pdf.numPages; i++) { await this.props.pdf.getPage(i + 1).then(page => runInAction(() => { // pageSizes[i] = { width: page.view[2] * scale, height: page.view[3] * scale }; let x = page.getViewport(scale); + page.getTextContent().then((text: Pdfjs.TextContent) => { + this._textContent[i] = text; + }) pageSizes[i] = { width: x.width, height: x.height }; })); } @@ -162,13 +184,6 @@ class Viewer extends React.Component { } } - private mainCont = (div: HTMLDivElement | null) => { - this._dropDisposer && this._dropDisposer(); - if (div) { - this._dropDisposer = div && DragManager.MakeDropTarget(div, { handlers: { drop: this.drop.bind(this) } }); - } - } - makeAnnotationDocument = (sourceDoc: Doc | undefined, s: number, color: string): Doc => { let annoDocs: Doc[] = []; let mainAnnoDoc = Docs.CreateInstance(new Doc(), "", {}); @@ -222,6 +237,7 @@ class Viewer extends React.Component { pageLoaded = (index: number, page: Pdfjs.PDFPageViewport): void => { this.props.loaded(page.width, page.height, this.props.pdf.numPages); } + @action getPlaceholderPage = (page: number) => { if (this._isPage[page] !== "none") { @@ -232,6 +248,7 @@ class Viewer extends React.Component { ); } } + @action getRenderedPage = (page: number) => { if (this._isPage[page] !== "page") { @@ -374,11 +391,16 @@ class Viewer extends React.Component { return res; } + pointerDown = () => { + + let x = this._textContent; + } + render() { let compiled = this._script; return ( -
-
+
+
{this._visibleElements}
{ } if (e.button === 2) { PDFMenu.Instance.Status = "annotation"; - PDFMenu.Instance.Delete = this.deleteAnnotation; + PDFMenu.Instance.Delete = this.deleteAnnotation.bind(this); PDFMenu.Instance.Pinned = false; + PDFMenu.Instance.AddTag = this.addTag.bind(this); PDFMenu.Instance.jumpTo(e.clientX, e.clientY, true); } } + addTag = (key: string, value: string): boolean => { + let group = FieldValue(Cast(this.props.document.group, Doc)); + if (group) { + let valNum = parseInt(value); + group[key] = isNaN(valNum) ? value : valNum; + return true; + } + return false; + } + render() { return (