aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts6
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx1
-rw-r--r--src/client/views/nodes/PDFBox.tsx4
-rw-r--r--src/client/views/pdf/PDFBox2.tsx28
-rw-r--r--src/client/views/pdf/PDFViewer.scss19
-rw-r--r--src/client/views/pdf/PDFViewer.tsx186
6 files changed, 242 insertions, 2 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 9d2f4d3cd..5752bb096 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -33,8 +33,12 @@ import { DocServer } from "../DocServer";
import { StrokeData, InkField } from "../../new_fields/InkField";
import { dropActionType } from "../util/DragManager";
import { DateField } from "../../new_fields/DateField";
+<<<<<<< HEAD
+import { PDFBox2 } from "../views/pdf/PDFBox2";
+=======
import { schema } from "prosemirror-schema-basic";
import { UndoManager } from "../util/UndoManager";
+>>>>>>> 01a223f2e6685506cc1e5db69e9062d5ff0d3246
export interface DocumentOptions {
x?: number;
@@ -170,7 +174,7 @@ export namespace Docs {
}
function CreatePdfPrototype(): Doc {
let pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionPDFView.LayoutString("annotations"),
- { x: 0, y: 0, nativeWidth: 1200, width: 300, backgroundLayout: PDFBox.LayoutString(), curPage: 1 });
+ { x: 0, y: 0, nativeWidth: 1200, width: 300, height: 300, backgroundLayout: PDFBox.LayoutString(), curPage: 1 });
return pdfProto;
}
function CreateWebPrototype(): Doc {
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index d2cb11586..8e08385a4 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -23,6 +23,7 @@ import { FieldViewProps } from "./FieldView";
import { Without, OmitKeys } from "../../../Utils";
import { Cast, StrCast, NumCast } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
+import { PDFBox2 } from "../pdf/PDFBox2";
const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
type BindingProps = Without<FieldViewProps, 'fieldKey'>;
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index e71ac4924..9b0207d0c 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -21,6 +21,7 @@ import { positionSchema } from "./DocumentView";
import { pageSchema } from "./ImageBox";
import { ImageField, PdfField } from "../../../new_fields/URLField";
import { InkingControl } from "../InkingControl";
+import { PDFViewer } from "../pdf/PDFViewer";
/** ALSO LOOK AT: Annotation.tsx, Sticky.tsx
* This method renders PDF and puts all kinds of functionalities such as annotation, highlighting,
@@ -340,10 +341,11 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
@action onKeyUp = (e: React.KeyboardEvent) => e.key === "Alt" && (this._alt = false);
render() {
trace();
+ const pdfUrl = window.origin + RouteStore.corsProxy + "/https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf";
let classname = "pdfBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !this._alt ? "-interactive" : "");
return (
<div className={classname} tabIndex={0} ref={this._mainDiv} onPointerDown={this.onPointerDown} onKeyDown={this.onKeyDown} onKeyUp={this.onKeyUp} >
- {this.pdfRenderer}
+ <PDFViewer url={pdfUrl} />
</div >
);
}
diff --git a/src/client/views/pdf/PDFBox2.tsx b/src/client/views/pdf/PDFBox2.tsx
new file mode 100644
index 000000000..71825c260
--- /dev/null
+++ b/src/client/views/pdf/PDFBox2.tsx
@@ -0,0 +1,28 @@
+import React = require("react");
+import { FieldViewProps, FieldView } from "../nodes/FieldView";
+import { DocComponent } from "../DocComponent";
+import { makeInterface } from "../../../new_fields/Schema";
+import { positionSchema } from "../nodes/DocumentView";
+import { pageSchema } from "../nodes/ImageBox";
+import { PDFViewer } from "./PDFViewer";
+import { RouteStore } from "../../../server/RouteStore";
+import { InkingControl } from "../InkingControl";
+import { observer } from "mobx-react";
+import { trace } from "mobx";
+
+type PdfDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>;
+const PdfDocument = makeInterface(positionSchema, pageSchema);
+
+@observer
+export class PDFBox2 extends DocComponent<FieldViewProps, PdfDocument>(PdfDocument) {
+ public static LayoutString() { return FieldView.LayoutString(PDFBox2); }
+
+ render() {
+ trace();
+ const pdfUrl = "https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf";
+ let classname = "pdfBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool);
+ return (
+ <PDFViewer url={pdfUrl} />
+ )
+ }
+} \ No newline at end of file
diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss
new file mode 100644
index 000000000..d8ff06406
--- /dev/null
+++ b/src/client/views/pdf/PDFViewer.scss
@@ -0,0 +1,19 @@
+.canvasContainer {}
+
+.viewer-button-cont {
+ position: absolute;
+ display: flex;
+ justify-content: space-evenly;
+ align-items: center;
+}
+
+.viewer-previousPage,
+.viewer-nextPage {
+ background: grey;
+ font-weight: bold;
+ opacity: 0.5;
+ padding: 0 10px;
+ border-radius: 5px;
+}
+
+.viewer {} \ No newline at end of file
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
new file mode 100644
index 000000000..1b445eae4
--- /dev/null
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -0,0 +1,186 @@
+import { observer } from "mobx-react";
+import React = require("react");
+import { observable, action, runInAction } from "mobx";
+import { RouteStore } from "../../../server/RouteStore";
+import * as Pdfjs from "pdfjs-dist";
+import { Opt } from "../../../new_fields/Doc";
+import "./PDFViewer.scss";
+
+interface IPDFViewerProps {
+ url: string;
+}
+
+@observer
+export class PDFViewer extends React.Component<IPDFViewerProps> {
+ @observable _pdf: Opt<Pdfjs.PDFDocumentProxy>;
+
+ @action
+ componentDidMount() {
+ // const pdfUrl = window.origin + RouteStore.corsProxy + "/https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf";
+ const pdfUrl = this.props.url;
+ let promise = Pdfjs.getDocument(pdfUrl).promise;
+
+ promise.then((pdf: Pdfjs.PDFDocumentProxy) => {
+ runInAction(() => this._pdf = pdf);
+ });
+ }
+
+ render() {
+ console.log("PDFVIEWER");
+ console.log(this._pdf);
+ return (
+ <div>
+ <Viewer pdf={this._pdf} />
+ </div>
+ );
+ }
+}
+
+interface IViewerProps {
+ pdf: Opt<Pdfjs.PDFDocumentProxy>;
+}
+
+class Viewer extends React.Component<IViewerProps> {
+ render() {
+ console.log("VIEWER");
+ let numPages = this.props.pdf ? this.props.pdf.numPages : 0;
+ console.log(numPages);
+ return (
+ <div className="viewer">
+ {Array.from(Array(numPages).keys()).map((i) => (
+ <Page
+ pdf={this.props.pdf}
+ page={i}
+ numPages={numPages}
+ key={`${this.props.pdf ? this.props.pdf.fingerprint + `page${i + 1}` : "undefined"}`}
+ name={`${this.props.pdf ? this.props.pdf.fingerprint + `page${i + 1}` : "undefined"}`}
+ {...this.props}
+ />
+ ))} }
+ </div>
+ );
+ }
+}
+
+interface IPageProps {
+ pdf: Opt<Pdfjs.PDFDocumentProxy>;
+ name: string;
+ numPages: number;
+ page: number;
+}
+
+@observer
+class Page extends React.Component<IPageProps> {
+ @observable _state: string = "N/A";
+ @observable _width: number = 0;
+ @observable _height: number = 0;
+ @observable _page: Opt<Pdfjs.PDFPageProxy>;
+ canvas: React.RefObject<HTMLCanvasElement>;
+ textLayer: React.RefObject<HTMLDivElement>;
+ @observable _currPage: number = this.props.page + 1;
+
+ constructor(props: IPageProps) {
+ super(props);
+ this.canvas = React.createRef();
+ this.textLayer = React.createRef();
+ }
+
+ componentDidMount() {
+ console.log(this.props.pdf);
+ if (this.props.pdf) {
+ this.update(this.props.pdf);
+ }
+ }
+
+ componentDidUpdate() {
+ if (this.props.pdf) {
+ this.update(this.props.pdf);
+ }
+ }
+
+ private update = (pdf: Pdfjs.PDFDocumentProxy) => {
+ if (pdf) {
+ this.loadPage(pdf);
+ }
+ else {
+ this._state = "loading";
+ }
+ }
+
+ private loadPage = (pdf: Pdfjs.PDFDocumentProxy) => {
+ if (this._state === "rendering" || this._page) return;
+
+ pdf.getPage(this._currPage).then(
+ (page: Pdfjs.PDFPageProxy) => {
+ console.log("PAGE");
+ console.log(page);
+ this._state = "rendering";
+ this.renderPage(page);
+ }
+ )
+ }
+
+ @action
+ private renderPage = (page: Pdfjs.PDFPageProxy) => {
+ let scale = 1;
+ let viewport = page.getViewport(scale);
+ let canvas = this.canvas.current;
+ if (canvas) {
+ let context = canvas.getContext("2d");
+ canvas.width = viewport.width;
+ this._width = viewport.width;
+ canvas.height = viewport.height;
+ this._height = viewport.height;
+ if (context) {
+ page.render({ canvasContext: context, viewport: viewport });
+ page.getTextContent().then((res: Pdfjs.TextContent) => {
+ //@ts-ignore
+ let textLayer = Pdfjs.renderTextLayer({
+ textContent: res,
+ container: this.textLayer.current,
+ viewport: viewport
+ });
+ // textLayer._render();
+ this._state = "rendered";
+ });
+
+ this._page = page;
+ }
+ }
+ }
+
+ @action
+ prevPage = (e: React.MouseEvent) => {
+ if (this._currPage > 2 && this._state !== "rendering") {
+ this._currPage = Math.max(this._currPage - 1, 1);
+ this._page = undefined;
+ this.loadPage(this.props.pdf!);
+ this._state = "rendering";
+ }
+ }
+
+ @action
+ nextPage = (e: React.MouseEvent) => {
+ if (this._currPage < this.props.numPages - 1 && this._state !== "rendering") {
+ this._currPage = Math.min(this._currPage + 1, this.props.numPages)
+ this._page = undefined;
+ this.loadPage(this.props.pdf!);
+ this._state = "rendering";
+ }
+ }
+
+ render() {
+ return (
+ <div className={this.props.name} style={{ "width": this._width, "height": this._height }}>
+ <div className="canvasContainer">
+ <canvas ref={this.canvas} />
+ </div>
+ <div className="textlayer" ref={this.textLayer} style={{ "position": "relative", "top": `-${this._height}px`, "height": `${this._height}px` }} />
+ {/* <div className="viewer-button-cont" style={{ "width": this._width / 10, "height": this._height / 20, "left": this._width * .9, "top": this._height * .95 }}>
+ <div className="viewer-previousPage" onClick={this.prevPage}>&lt;</div>
+ <div className="viewer-nextPage" onClick={this.nextPage}>&gt;</div>
+ </div> */}
+ </div>
+ );
+ }
+} \ No newline at end of file