aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/pdf
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/pdf')
-rw-r--r--src/client/views/pdf/Annotation.tsx33
-rw-r--r--src/client/views/pdf/PDFViewer.tsx37
-rw-r--r--src/client/views/pdf/Page.tsx18
3 files changed, 59 insertions, 29 deletions
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 7ba7b6d14..eeb2531a2 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -1,23 +1,21 @@
import React = require("react");
-import { action, IReactionDisposer, observable, reaction } from "mobx";
+import { action, IReactionDisposer, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
import { Doc, DocListCast, HeightSym, WidthSym } from "../../../new_fields/Doc";
import { Id } from "../../../new_fields/FieldSymbols";
import { List } from "../../../new_fields/List";
import { Cast, FieldValue, NumCast, StrCast } from "../../../new_fields/Types";
import { DocumentManager } from "../../util/DocumentManager";
-import { PresentationView } from "../presentationview/PresentationView";
import PDFMenu from "./PDFMenu";
import "./Annotation.scss";
import { scale } from "./PDFViewer";
+import { PresBox } from "../nodes/PresBox";
interface IAnnotationProps {
anno: Doc;
- index: number;
- ParentIndex: () => number;
fieldExtensionDoc: Doc;
- scrollTo?: (n: number) => void;
addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void;
+ pinToPres: (document: Doc) => void;
}
export default class Annotation extends React.Component<IAnnotationProps> {
@@ -32,20 +30,20 @@ interface IRegionAnnotationProps {
y: number;
width: number;
height: number;
- index: number;
- ParentIndex: () => number;
fieldExtensionDoc: Doc;
- scrollTo?: (n: number) => void;
addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void;
+ pinToPres: (document: Doc) => void;
document: Doc;
}
@observer
class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
private _reactionDisposer?: IReactionDisposer;
- private _scrollDisposer?: IReactionDisposer;
+ private _brushDisposer?: IReactionDisposer;
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
+ @observable private _brushed: boolean = false;
+
componentDidMount() {
this._reactionDisposer = reaction(
() => this.props.document.delete,
@@ -53,15 +51,18 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
{ fireImmediately: true }
);
- this._scrollDisposer = reaction(
- () => this.props.ParentIndex(),
- (ind) => ind === this.props.index && this.props.scrollTo && this.props.scrollTo(this.props.y * scale)
- );
+ this._brushDisposer = reaction(
+ () => FieldValue(Cast(this.props.document.group, Doc)) && Doc.IsBrushed(FieldValue(Cast(this.props.document.group, Doc))!),
+ (brushed) => {
+ if (brushed !== undefined) {
+ runInAction(() => this._brushed = brushed);
+ }
+ }
+ )
}
componentWillUnmount() {
this._reactionDisposer && this._reactionDisposer();
- this._scrollDisposer && this._scrollDisposer();
}
deleteAnnotation = () => {
@@ -81,7 +82,7 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
pinToPres = () => {
let group = FieldValue(Cast(this.props.document.group, Doc));
- group && PresentationView.Instance.PinDoc(group);
+ group && this.props.pinToPres(group);
}
@action
@@ -124,7 +125,7 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
left: this.props.x,
width: this.props.width,
height: this.props.height,
- backgroundColor: this.props.ParentIndex() === this.props.index ? "green" : StrCast(this.props.document.color)
+ backgroundColor: this._brushed ? "green" : StrCast(this.props.document.color)
}} />);
}
} \ No newline at end of file
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 08674720d..7bc1d3507 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -36,6 +36,7 @@ interface IViewerProps {
active: () => boolean;
setPanY?: (n: number) => void;
addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void;
+ pinToPres: (document: Doc) => void;
addDocument?: (doc: Doc, allowDuplicates?: boolean) => boolean;
}
@@ -75,7 +76,15 @@ export class PDFViewer extends React.Component<IViewerProps> {
return Math.min(this.props.pdf.numPages - 1, this.getPageFromScroll(this.panY + (this._pageSizes[0] ? this._pageSizes[0].height : 0)) + this._pageBuffer);
}
- @computed get filteredAnnotations() {
+ @computed get allAnnotations() {
+ let annotations = DocListCast(this.props.fieldExtensionDoc.annotations);
+ return annotations.filter(anno => {
+ let run = this._script.run({ this: anno });
+ return run.success ? run.result : true;
+ })
+ }
+
+ @computed get nonDocAnnotations() {
return this._annotations.filter(anno => {
let run = this._script.run({ this: anno });
return run.success ? run.result : true;
@@ -100,12 +109,15 @@ export class PDFViewer extends React.Component<IViewerProps> {
this._filterReactionDisposer = reaction(
() => ({ scriptField: Cast(this.props.Document.filterScript, ScriptField), annos: this._annotations.slice() }),
action(({ scriptField, annos }: { scriptField: FieldResult<ScriptField>, annos: Doc[] }) => {
+ let oldScript = this._script.originalScript;
this._script = scriptField && scriptField.script.compiled ? scriptField.script : CompileScript("return true") as CompiledScript;
+ if (this._script.originalScript !== oldScript) {
+ this.Index = -1;
+ }
annos.forEach(d => {
let run = this._script.run(d);
d.opacity = !run.success || run.result ? 1 : 0;
});
- this.Index = -1;
}),
{ fireImmediately: true }
);
@@ -151,18 +163,25 @@ export class PDFViewer extends React.Component<IViewerProps> {
if (this._pageSizes.length === 0) {
this._isPage = Array<string>(this.props.pdf.numPages);
this._pageSizes = Array<{ width: number, height: number }>(this.props.pdf.numPages);
+ this._visibleElements = Array<JSX.Element>(this.props.pdf.numPages);
await Promise.all(this._pageSizes.map<Pdfjs.PDFPromise<any>>((val, i) =>
this.props.pdf.getPage(i + 1).then(action((page: Pdfjs.PDFPageProxy) => {
this._pageSizes.splice(i, 1, {
width: (page.view[page.rotate === 0 || page.rotate === 180 ? 2 : 3] - page.view[page.rotate === 0 || page.rotate === 180 ? 0 : 1]) * scale,
height: (page.view[page.rotate === 0 || page.rotate === 180 ? 3 : 2] - page.view[page.rotate === 0 || page.rotate === 180 ? 1 : 0]) * scale
});
+ this._visibleElements.splice(i, 1,
+ <div key={`${this.props.url}-placeholder-${i + 1}`} className="pdfviewer-placeholder"
+ style={{ width: this._pageSizes[i].width, height: this._pageSizes[i].height }}>
+ "PAGE IS LOADING... "
+ </div>);
this.getPlaceholderPage(i);
}))));
this.props.loaded(Math.max(...this._pageSizes.map(i => i.width)), this._pageSizes[0].height, this.props.pdf.numPages);
let startY = NumCast(this.props.Document.startY, NumCast(this.props.Document.panY));
this.props.setPanY && this.props.setPanY(startY);
+ this.props.scrollTo(startY);
}
}
@@ -288,12 +307,20 @@ export class PDFViewer extends React.Component<IViewerProps> {
prevAnnotation = (e: React.MouseEvent) => {
e.stopPropagation();
this.Index = Math.max(this.Index - 1, 0);
+ let scrollToAnnotation = this.allAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y))[this.Index];
+ this.allAnnotations.forEach(d => Doc.UnBrushDoc(d));
+ Doc.BrushDoc(scrollToAnnotation);
+ this.props.scrollTo(NumCast(scrollToAnnotation.y));
}
@action
nextAnnotation = (e: React.MouseEvent) => {
e.stopPropagation();
- this.Index = Math.min(this.Index + 1, this.filteredAnnotations.length - 1);
+ this.Index = Math.min(this.Index + 1, this.allAnnotations.length - 1);
+ let scrollToAnnotation = this.allAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y))[this.Index];
+ this.allAnnotations.forEach(d => Doc.UnBrushDoc(d));
+ Doc.BrushDoc(scrollToAnnotation);
+ this.props.scrollTo(NumCast(scrollToAnnotation.y));
}
sendAnnotations = (page: number) => {
@@ -406,8 +433,8 @@ export class PDFViewer extends React.Component<IViewerProps> {
</div>
<div className="pdfViewer-text" ref={this._viewer} />
<div className="pdfViewer-annotationLayer" style={{ height: NumCast(this.props.Document.nativeHeight) }} ref={this._annotationLayer}>
- {this.filteredAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map((anno, index) =>
- <Annotation {...this.props} ParentIndex={this.getIndex} anno={anno} index={index} key={`${anno[Id]}-annotation`} />)}
+ {this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map((anno, index) =>
+ <Annotation {...this.props} anno={anno} key={`${anno[Id]}-annotation`} />)}
</div>
<div className="pdfViewer-overlayCont" onPointerDown={(e) => e.stopPropagation()}
style={{ bottom: -this.props.panY, left: `${this._searching ? 0 : 100}%` }}>
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
index 7ca9d2d7d..856e883e7 100644
--- a/src/client/views/pdf/Page.tsx
+++ b/src/client/views/pdf/Page.tsx
@@ -19,8 +19,8 @@ interface IPageProps {
numPages: number;
page: number;
pageLoaded: (page: Pdfjs.PDFPageViewport) => void;
- fieldExtensionDoc: Doc,
- Document: Doc,
+ fieldExtensionDoc: Doc;
+ Document: Doc;
renderAnnotations: (annotations: Doc[], removeOld: boolean) => void;
sendAnnotations: (annotations: HTMLDivElement[], page: number) => void;
createAnnotation: (div: HTMLDivElement, page: number) => void;
@@ -70,7 +70,8 @@ export default class Page extends React.Component<IPageProps> {
this.props.pageLoaded(viewport);
let ctx = this._canvas.current.getContext("2d");
if (ctx) {
- page.render({ canvasContext: ctx, viewport: viewport }); // renders the page onto the canvas context
+ //@ts-ignore
+ page.render({ canvasContext: ctx, viewport: viewport, enableWebGL: true }); // renders the page onto the canvas context
page.getTextContent().then(res => // renders text onto the text container
//@ts-ignore
Pdfjs.renderTextLayer({
@@ -112,7 +113,7 @@ export default class Page extends React.Component<IPageProps> {
if (!BoolCast(annotationDoc.linkedToDoc)) {
let annotations = await DocListCastAsync(annotationDoc.annotations);
annotations && annotations.forEach(anno => anno.target = targetDoc);
- DocUtils.MakeLink(annotationDoc, targetDoc, dragData.targetContext, `Annotation from ${StrCast(this.props.Document.title)}`)
+ DocUtils.MakeLink(annotationDoc, targetDoc, dragData.targetContext, `Annotation from ${StrCast(this.props.Document.title)}`);
}
}
},
@@ -151,6 +152,9 @@ export default class Page extends React.Component<IPageProps> {
PDFMenu.Instance.fadeOut(true);
if (e.target && (e.target as any).parentElement === this._textLayer.current) {
e.stopPropagation();
+ if (!e.ctrlKey) {
+ this.props.sendAnnotations([], -1);
+ }
}
else {
// set marquee x and y positions to the spatially transformed position
@@ -161,14 +165,12 @@ export default class Page extends React.Component<IPageProps> {
}
this._marqueeing = true;
this._marquee.current && (this._marquee.current.style.opacity = "0.2");
+ this.props.sendAnnotations([], -1);
}
document.removeEventListener("pointermove", this.onSelectStart);
document.addEventListener("pointermove", this.onSelectStart);
document.removeEventListener("pointerup", this.onSelectEnd);
document.addEventListener("pointerup", this.onSelectEnd);
- if (!e.ctrlKey) {
- this.props.sendAnnotations([], -1);
- }
}
}
@@ -257,7 +259,7 @@ export default class Page extends React.Component<IPageProps> {
}
}
}
- let text = selRange.extractContents().textContent;
+ let text = selRange.cloneContents().textContent;
text && this.props.setSelectionText(text);
// clear selection