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/collections/CollectionPDFView.tsx | 4 ++ src/client/views/nodes/DocumentView.tsx | 13 +++- src/client/views/nodes/PDFBox.tsx | 44 ++++++++++--- src/client/views/pdf/PDFMenu.scss | 7 ++ src/client/views/pdf/PDFMenu.tsx | 55 +++++++++++----- src/client/views/pdf/PDFViewer.tsx | 75 ++++++++++++++++------ 6 files changed, 152 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx index b2d016934..31a73ab36 100644 --- a/src/client/views/collections/CollectionPDFView.tsx +++ b/src/client/views/collections/CollectionPDFView.tsx @@ -43,6 +43,10 @@ export class CollectionPDFView extends React.Component { ); } + componentWillUnmount() { + this._reactionDisposer && this._reactionDisposer(); + } + public static LayoutString(fieldKey: string = "data") { return FieldView.LayoutString(CollectionPDFView, fieldKey); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 522c37989..f5a3f4d5d 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -117,6 +117,8 @@ export class DocumentView extends DocComponent(Docu private _mainCont = React.createRef(); private _dropDisposer?: DragManager.DragDropDisposer; + @observable private _opacity: number = this.Document.opacity ? NumCast(this.Document.opacity) : 1; + public get ContentDiv() { return this._mainCont.current; } @computed get active(): boolean { return SelectionManager.IsSelected(this) || this.props.parentActive(); } @computed get topMost(): boolean { return this.props.isTopMost; } @@ -136,6 +138,7 @@ export class DocumentView extends DocComponent(Docu _animateToIconDisposer?: IReactionDisposer; _reactionDisposer?: IReactionDisposer; + _opacityDisposer?: IReactionDisposer; @action componentDidMount() { if (this._mainCont.current) { @@ -160,6 +163,12 @@ export class DocumentView extends DocComponent(Docu (values instanceof List) && this.animateBetweenIcon(values, values[2], values[3] ? true : false) , { fireImmediately: true }); DocumentManager.Instance.DocumentViews.push(this); + this._opacityDisposer = reaction( + () => NumCast(this.props.Document.opacity), + () => { + runInAction(() => this._opacity = NumCast(this.props.Document.opacity)); + } + ); } animateBetweenIcon = (iconPos: number[], startTime: number, maximizing: boolean) => { @@ -201,6 +210,7 @@ export class DocumentView extends DocComponent(Docu if (this._reactionDisposer) this._reactionDisposer(); if (this._animateToIconDisposer) this._animateToIconDisposer(); if (this._dropDisposer) this._dropDisposer(); + if (this._opacityDisposer) this._opacityDisposer(); DocumentManager.Instance.DocumentViews.splice(DocumentManager.Instance.DocumentViews.indexOf(this), 1); } @@ -559,7 +569,8 @@ export class DocumentView extends DocComponent(Docu background: this.Document.backgroundColor || "", width: nativeWidth, height: nativeHeight, - transform: `scale(${scaling}, ${scaling})` + transform: `scale(${scaling}, ${scaling})`, + opacity: this._opacity }} onDrop={this.onDrop} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick} diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index a129e89b9..c0f2d313a 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -18,9 +18,9 @@ import { pageSchema } from "./ImageBox"; import "./PDFBox.scss"; import React = require("react"); import { CompileScript } from '../../util/Scripting'; -import { ScriptField } from '../../../fields/ScriptField'; import { Flyout, anchorPoints } from '../DocumentDecorations'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { ScriptField } from '../../../new_fields/ScriptField'; type PdfDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>; const PdfDocument = makeInterface(positionSchema, pageSchema); @@ -37,6 +37,9 @@ export class PDFBox extends DocComponent(PdfDocumen private _keyValue: string = ""; private _valueValue: string = ""; private _scriptValue: string = ""; + private _keyRef: React.RefObject; + private _valueRef: React.RefObject; + private _scriptRef: React.RefObject; constructor(props: FieldViewProps) { super(props); @@ -51,10 +54,9 @@ export class PDFBox extends DocComponent(PdfDocumen } ); - let script = CompileScript("return this.page === 0", { params: { this: Doc.name } }); - if (script.compiled) { - this.props.Document.filterScript = new ScriptField(script); - } + this._keyRef = React.createRef(); + this._valueRef = React.createRef(); + this._scriptRef = React.createRef(); } componentDidMount() { @@ -99,17 +101,21 @@ export class PDFBox extends DocComponent(PdfDocumen this._valueValue = e.currentTarget.value; } + @action private newScriptChange = (e: React.ChangeEvent) => { this._scriptValue = e.currentTarget.value; } - private applyFilter = (e: React.MouseEvent) => { + private applyFilter = () => { let scriptText = ""; if (this._scriptValue.length > 0) { scriptText = this._scriptValue; } else if (this._keyValue.length > 0 && this._valueValue.length > 0) { scriptText = `return this.${this._keyValue} === ${this._valueValue}`; } + else { + scriptText = "return true"; + } let script = CompileScript(scriptText, { params: { this: Doc.name } }); if (script.compiled) { this.props.Document.filterScript = new ScriptField(script); @@ -121,6 +127,22 @@ export class PDFBox extends DocComponent(PdfDocumen this._flyout = !this._flyout; } + @action + private resetFilters = () => { + this._keyValue = this._valueValue = ""; + this._scriptValue = "return true"; + if (this._keyRef.current) { + this._keyRef.current.value = ""; + } + if (this._valueRef.current) { + this._valueRef.current.value = ""; + } + if (this._scriptRef.current) { + this._scriptRef.current.value = ""; + } + this.applyFilter(); + } + settingsPanel() { return !this.props.active() ? (null) : ( @@ -144,14 +166,18 @@ export class PDFBox extends DocComponent(PdfDocumen
+ style={{ gridColumn: 1 }} ref={this._keyRef} /> + style={{ gridColumn: 3 }} ref={this._valueRef} />
- +
+ , - , + , 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 (