aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/pdf/PDFViewer.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/pdf/PDFViewer.tsx')
-rw-r--r--src/client/views/pdf/PDFViewer.tsx83
1 files changed, 50 insertions, 33 deletions
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 198aeb856..f93c1fa97 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -4,12 +4,12 @@ import * as Pdfjs from "pdfjs-dist";
import "pdfjs-dist/web/pdf_viewer.css";
import { Dictionary } from "typescript-collections";
import { Doc, DocListCast, FieldResult, WidthSym, Opt, HeightSym } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
+import { Id, Copy } from "../../../new_fields/FieldSymbols";
import { List } from "../../../new_fields/List";
import { makeInterface, createSchema } from "../../../new_fields/Schema";
-import { ScriptField } from "../../../new_fields/ScriptField";
+import { ScriptField, ComputedField } from "../../../new_fields/ScriptField";
import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { smoothScroll, Utils, emptyFunction, returnOne, intersectRect, addStyleSheet, addStyleSheetRule, clearStyleSheetRules } from "../../../Utils";
+import { smoothScroll, Utils, emptyFunction, returnOne, intersectRect, addStyleSheet, addStyleSheetRule, clearStyleSheetRules, returnZero } from "../../../Utils";
import { Docs, DocUtils } from "../../documents/Documents";
import { DragManager } from "../../util/DragManager";
import { CompiledScript, CompileScript } from "../../util/Scripting";
@@ -31,6 +31,7 @@ import { InkingControl } from "../InkingControl";
import { InkTool } from "../../../new_fields/InkField";
import { TraceMobx } from "../../../new_fields/util";
import { PdfField } from "../../../new_fields/URLField";
+import { DocumentView } from "../nodes/DocumentView";
const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer");
const pdfjsLib = require("pdfjs-dist");
@@ -58,6 +59,7 @@ interface IViewerProps {
PanelHeight: () => number;
ContentScaling: () => number;
select: (isCtrlPressed: boolean) => void;
+ rootSelected: (outsideReaction?: boolean) => boolean;
startupLive: boolean;
renderDepth: number;
focus: (doc: Doc) => void;
@@ -101,6 +103,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
private _reactionDisposer?: IReactionDisposer;
private _selectionReactionDisposer?: IReactionDisposer;
private _annotationReactionDisposer?: IReactionDisposer;
+ private _scrollTopReactionDisposer?: IReactionDisposer;
private _filterReactionDisposer?: IReactionDisposer;
private _searchReactionDisposer?: IReactionDisposer;
private _viewer: React.RefObject<HTMLDivElement> = React.createRef();
@@ -126,7 +129,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
!this.props.Document.lockedTransform && (this.props.Document.lockedTransform = true);
// change the address to be the file address of the PNG version of each page
// file address of the pdf
- const { url: { href } } = Cast(this.props.Document[this.props.fieldKey], PdfField)!;
+ const { url: { href } } = Cast(this.dataDoc[this.props.fieldKey], PdfField)!;
const addr = Utils.prepend(`/thumbnail${this.props.url.substring("files/pdfs/".length, this.props.url.length - ".pdf".length)}-${(this.Document.curPage || 1)}.png`);
this._coverPath = href.startsWith(window.location.origin) ? JSON.parse(await rp.get(addr)) : { width: 100, height: 100, path: "" };
runInAction(() => this._showWaiting = this._showCover = true);
@@ -161,11 +164,12 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
}
componentWillUnmount = () => {
- this._reactionDisposer && this._reactionDisposer();
- this._annotationReactionDisposer && this._annotationReactionDisposer();
- this._filterReactionDisposer && this._filterReactionDisposer();
- this._selectionReactionDisposer && this._selectionReactionDisposer();
- this._searchReactionDisposer && this._searchReactionDisposer();
+ this._reactionDisposer?.();
+ this._scrollTopReactionDisposer?.();
+ this._annotationReactionDisposer?.();
+ this._filterReactionDisposer?.();
+ this._selectionReactionDisposer?.();
+ this._searchReactionDisposer?.();
document.removeEventListener("copy", this.copy);
}
@@ -206,6 +210,8 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
this.props.setPdfViewer(this);
await this.initialLoad();
+ this._scrollTopReactionDisposer = reaction(() => Cast(this.layoutDoc._scrollTop, "number", null),
+ (stop) => (stop !== undefined) && this._mainCont.current && smoothScroll(500, this._mainCont.current, stop), { fireImmediately: true });
this._annotationReactionDisposer = reaction(
() => DocListCast(this.dataDoc[this.props.fieldKey + "-annotations"]),
annotations => annotations?.length && (this._annotations = annotations),
@@ -227,6 +233,12 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
this.createPdfViewer();
}
+ pagesinit = action(() => {
+ this._pdfViewer.currentScaleValue = this._zoomed = 1;
+ this.gotoPage(this.Document.curPage || 1);
+ document.removeEventListener("pagesinit", this.pagesinit);
+ });
+
createPdfViewer() {
if (!this._mainCont.current) { // bcz: I don't think this is ever triggered or needed
if (this._retries < 5) {
@@ -237,10 +249,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
}
document.removeEventListener("copy", this.copy);
document.addEventListener("copy", this.copy);
- document.addEventListener("pagesinit", action(() => {
- this._pdfViewer.currentScaleValue = this._zoomed = 1;
- this.gotoPage(this.Document.curPage || 1);
- }));
+ document.addEventListener("pagesinit", this.pagesinit);
document.addEventListener("pagerendered", action(() => this._showCover = this._showWaiting = false));
const pdfLinkService = new PDFJSViewer.PDFLinkService();
const pdfFindController = new PDFJSViewer.PDFFindController({ linkService: pdfLinkService });
@@ -267,13 +276,13 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
let minY = Number.MAX_VALUE;
if ((this._savedAnnotations.values()[0][0] as any).marqueeing) {
const anno = this._savedAnnotations.values()[0][0];
- const annoDoc = Docs.Create.FreeformDocument([], { backgroundColor: color, title: "Annotation on " + this.Document.title });
+ const annoDoc = Docs.Create.FreeformDocument([], { backgroundColor: color, _LODdisable: true, title: "Annotation on " + this.Document.title });
if (anno.style.left) annoDoc.x = parseInt(anno.style.left);
if (anno.style.top) annoDoc.y = parseInt(anno.style.top);
if (anno.style.height) annoDoc._height = parseInt(anno.style.height);
if (anno.style.width) annoDoc._width = parseInt(anno.style.width);
annoDoc.group = mainAnnoDoc;
- annoDoc.isButton = true;
+ annoDoc.isLinkButton = true;
annoDocs.push(annoDoc);
anno.remove();
mainAnnoDoc = annoDoc;
@@ -320,7 +329,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
@action
gotoPage = (p: number) => {
- this._pdfViewer && this._pdfViewer.scrollPageIntoView({ pageNumber: Math.min(Math.max(1, p), this._pageSizes.length) });
+ this._pdfViewer?.scrollPageIntoView({ pageNumber: Math.min(Math.max(1, p), this._pageSizes.length) });
}
@action
@@ -554,32 +563,35 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
* start a drag event and create or put the necessary info into the drag event.
*/
@action
- startDrag = (e: PointerEvent, ele: HTMLElement): void => {
+ startDrag = async (e: PointerEvent, ele: HTMLElement) => {
e.preventDefault();
e.stopPropagation();
+
+ const clipDoc = Doc.MakeAlias(this.dataDoc);
+ clipDoc._fitWidth = true;
+ clipDoc._width = this.marqueeWidth();
+ clipDoc._height = this.marqueeHeight();
+ clipDoc._scrollTop = this.marqueeY();
const targetDoc = Docs.Create.TextDocument("", { _width: 200, _height: 200, title: "Note linked to " + this.props.Document.title });
+ Doc.GetProto(targetDoc).data = new List<Doc>([clipDoc]);
+ DocumentView.makeCustomViewClicked(targetDoc, Docs.Create.StackingDocument, "slideView", undefined);
+ // const targetDoc = Docs.Create.TextDocument("", { _width: 200, _height: 200, title: "Note linked to " + this.props.Document.title });
+ // Doc.GetProto(targetDoc).snipped = this.dataDoc[this.props.fieldKey][Copy]();
+ // const snipLayout = Docs.Create.PdfDocument("http://www.msn.com", { title: "snippetView", isTemplateDoc: true, isTemplateForField: "snipped", _fitWidth: true, _width: this.marqueeWidth(), _height: this.marqueeHeight(), _scrollTop: this.marqueeY() });
+ // Doc.GetProto(snipLayout).layout = PDFBox.LayoutString("snipped");
const annotationDoc = this.highlight("rgba(146, 245, 95, 0.467)"); // yellowish highlight color when dragging out a text selection
if (annotationDoc) {
DragManager.StartPdfAnnoDrag([ele], new DragManager.PdfAnnoDragData(this.props.Document, annotationDoc, targetDoc), e.pageX, e.pageY, {
- dragComplete: e => !e.aborted && e.annoDragData && !e.annoDragData.linkedToDoc &&
- DocUtils.MakeLink({ doc: annotationDoc }, { doc: e.annoDragData.dropDocument, ctx: e.annoDragData.targetContext }, `Annotation from ${this.Document.title}`, "link from PDF")
+ dragComplete: e => {
+ if (!e.aborted && e.annoDragData && !e.annoDragData.linkedToDoc) {
+ const link = DocUtils.MakeLink({ doc: annotationDoc }, { doc: e.annoDragData.dropDocument }, "Annotation");
+ if (link) link.followLinkLocation = "onRight";
+ }
+ }
});
}
}
- createSnippet = (marquee: { left: number, top: number, width: number, height: number }): void => {
- const view = Doc.MakeAlias(this.props.Document);
- const data = Doc.MakeDelegate(Doc.GetProto(this.props.Document));
- data.title = StrCast(data.title) + "_snippet";
- view.proto = data;
- view._nativeHeight = marquee.height;
- view._height = (this.Document[WidthSym]() / (this.Document._nativeWidth || 1)) * marquee.height;
- view._nativeWidth = this.Document._nativeWidth;
- view.startY = marquee.top;
- view._width = this.Document[WidthSym]();
- DragManager.StartDocumentDrag([], new DragManager.DocumentDragData([view]), 0, 0);
- }
-
scrollXf = () => {
return this._mainCont.current ? this.props.ScreenToLocalTransform().translate(0, this._scrollTop) : this.props.ScreenToLocalTransform();
}
@@ -636,6 +648,9 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
setPreviewCursor={this.setPreviewCursor}
PanelHeight={this.panelWidth}
PanelWidth={this.panelHeight}
+ NativeHeight={returnZero}
+ NativeWidth={returnZero}
+ dropAction={"alias"}
VisibleHeight={this.visibleHeight}
focus={this.props.focus}
isSelected={this.props.isSelected}
@@ -643,6 +658,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
select={emptyFunction}
active={this.annotationsActive}
ContentScaling={this.contentZoom}
+ bringToFront={emptyFunction}
whenActiveChanged={this.whenActiveChanged}
removeDocument={this.removeDocument}
moveDocument={this.moveDocument}
@@ -673,9 +689,10 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
contentZoom = () => this._zoomed;
render() {
TraceMobx();
- return <div className={"pdfViewer" + (this._zoomed !== 1 ? "-zoomed" : "")} ref={this._mainCont}
+ return <div className={"pdfViewer" + (this.active() ? "-interactive" : "")} ref={this._mainCont}
onScroll={this.onScroll} onWheel={this.onZoomWheel} onPointerDown={this.onPointerDown} onClick={this.onClick}
style={{
+ overflowX: this._zoomed !== 1 ? "scroll" : undefined,
width: !this.props.Document._fitWidth ? NumCast(this.props.Document._nativeWidth) : `${100 / this.contentScaling}%`,
height: !this.props.Document._fitWidth ? NumCast(this.props.Document._nativeHeight) : `${100 / this.contentScaling}%`,
transform: `scale(${this.props.ContentScaling()})`