From e96d0be82b19a4e108447ba5afc6cdc5deb07110 Mon Sep 17 00:00:00 2001 From: yipstanley Date: Fri, 7 Jun 2019 15:28:25 -0400 Subject: starting annotation dragss --- src/client/util/DragManager.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/client/util/DragManager.ts') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 1e84a0db0..a6c3dfa7a 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -153,6 +153,22 @@ export namespace DragManager { [id: string]: any; } + export class AnnotationDragData { + constructor(dragDoc: Doc, annotationDocs: Doc[], dropDoc: Doc) { + this.dragDocument = dragDoc; + this.dropDocument = dropDoc; + this.annotationDocuments = annotationDocs; + this.xOffset = this.yOffset = 0; + } + dragDocument: Doc; + annotationDocuments: Doc[]; + dropDocument: Doc; + xOffset: number; + yOffset: number; + dropAction: dropActionType; + userDropAction: dropActionType; + } + export let StartDragFunctions: (() => void)[] = []; export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions) { @@ -166,6 +182,10 @@ export namespace DragManager { dragData.draggedDocuments)); } + export function StartAnnotationDrag(eles: HTMLElement[], dragData: AnnotationDragData, downX: number, downY: number, options?: DragOptions) { + StartDrag(eles, dragData, downX, downY, options); + } + export class LinkDragData { constructor(linkSourceDoc: Doc, blacklist: Doc[] = []) { this.linkSourceDocument = linkSourceDoc; -- cgit v1.2.3-70-g09d2 From 5d799d1a26fa12d666b11b80776151edcbbd67f8 Mon Sep 17 00:00:00 2001 From: loudonclear Date: Fri, 7 Jun 2019 18:14:39 -0400 Subject: some comments, switching computers --- src/client/util/DragManager.ts | 2 +- src/client/views/collections/CollectionSubView.tsx | 5 + src/client/views/pdf/PDFBox2.tsx | 28 -- src/client/views/pdf/PDFViewer.tsx | 327 +----------------- src/client/views/pdf/Page.tsx | 382 +++++++++++++++++++++ 5 files changed, 391 insertions(+), 353 deletions(-) delete mode 100644 src/client/views/pdf/PDFBox2.tsx create mode 100644 src/client/views/pdf/Page.tsx (limited to 'src/client/util/DragManager.ts') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index a6c3dfa7a..e92ed9b4a 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -218,7 +218,7 @@ export namespace DragManager { let ys: number[] = []; const docs: Doc[] = - dragData instanceof DocumentDragData ? dragData.draggedDocuments : []; + dragData instanceof DocumentDragData ? dragData.draggedDocuments : dragData instanceof AnnotationDragData ? [dragData.dragDocument] : []; let dragElements = eles.map(ele => { const w = ele.offsetWidth, h = ele.offsetHeight; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index be37efd3d..1ced6a426 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -107,6 +107,11 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { e.stopPropagation(); return added; } + else if (de.data instanceof DragManager.AnnotationDragData) { + console.log("dropped!"); + console.log(de.data); + return this.props.addDocument(de.data.dropDocument); + } return false; } diff --git a/src/client/views/pdf/PDFBox2.tsx b/src/client/views/pdf/PDFBox2.tsx deleted file mode 100644 index 71825c260..000000000 --- a/src/client/views/pdf/PDFBox2.tsx +++ /dev/null @@ -1,28 +0,0 @@ -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(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 ( - - ) - } -} \ No newline at end of file diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index b0a48ac84..0711ead23 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -2,19 +2,11 @@ import { observer } from "mobx-react"; import React = require("react"); import { observable, action, runInAction, computed, IReactionDisposer, reaction } from "mobx"; import * as Pdfjs from "pdfjs-dist"; -import { Opt, Doc, HeightSym, WidthSym, Field, DocListCast } from "../../../new_fields/Doc"; +import { Opt } from "../../../new_fields/Doc"; import "./PDFViewer.scss"; import "pdfjs-dist/web/pdf_viewer.css"; import { PDFBox } from "../nodes/PDFBox"; -import { PDFAnnotationLayer } from "./PDFAnnotationLayer"; -import { TSMethodSignature } from "babel-types"; -import { checkPropTypes } from "prop-types"; -import { DragManager } from "../../util/DragManager"; -import { Docs } from "../../documents/Documents"; -import { List } from "../../../new_fields/List"; -import { Cast } from "../../../new_fields/Types"; -import { emptyFunction } from "../../../Utils"; -const Curly = require("./curly.png"); +import Page from "./Page"; interface IPDFViewerProps { url: string; @@ -168,7 +160,7 @@ class Viewer extends React.Component { parent={this.props.parent} {...this.props} /> )); - let arr = Array.from(Array(numPages).keys()).map(i => false); + let arr = Array.from(Array(numPages).keys()).map(() => false); this._visibleElements.push(...divs); this._isPage.push(...arr); } @@ -263,316 +255,3 @@ class Viewer extends React.Component { ); } } - -interface IPageProps { - pdf: Opt; - name: string; - numPages: number; - page: number; - pageLoaded: (index: number, page: Pdfjs.PDFPageViewport) => void; - parent: PDFBox; -} - -@observer -class Page extends React.Component { - @observable private _state: string = "N/A"; - @observable private _width: number = 0; - @observable private _height: number = 0; - @observable private _page: Opt; - @observable private _currPage: number = this.props.page + 1; - @observable private _marqueeX: number = 0; - @observable private _marqueeY: number = 0; - @observable private _marqueeWidth: number = 0; - @observable private _marqueeHeight: number = 0; - @observable private _rotate: string = ""; - - private _canvas: React.RefObject; - private _textLayer: React.RefObject; - private _annotationLayer: React.RefObject; - private _marquee: React.RefObject; - private _curly: React.RefObject; - private _currentAnnotations: HTMLDivElement[] = []; - private _marqueeing: boolean = false; - - constructor(props: IPageProps) { - super(props); - this._canvas = React.createRef(); - this._textLayer = React.createRef(); - this._annotationLayer = React.createRef(); - this._marquee = React.createRef(); - this._curly = React.createRef(); - } - - componentDidMount() { - 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) => { - 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; - let textLayer = this._textLayer.current; - if (canvas && textLayer) { - let ctx = canvas.getContext("2d"); - canvas.width = viewport.width; - this._width = viewport.width; - canvas.height = viewport.height; - this._height = viewport.height; - this.props.pageLoaded(this._currPage, viewport); - if (ctx) { - // renders the page onto the canvas context - page.render({ canvasContext: ctx, viewport: viewport }); - // renders text onto the text container - page.getTextContent().then((res: Pdfjs.TextContent) => { - //@ts-ignore - Pdfjs.renderTextLayer({ - textContent: res, - container: textLayer, - viewport: viewport - }); - }); - - this._page = page; - } - } - } - - makeAnnotationDocuments = (targetDoc: Doc): Doc[] => { - let annoDocs: Doc[] = []; - for (let anno of this._currentAnnotations) { - let annoDoc = new Doc(); - annoDoc.x = anno.offsetLeft; - annoDoc.y = anno.offsetTop; - annoDoc.height = anno.offsetHeight; - annoDoc.width = anno.offsetWidth; - annoDoc.target = targetDoc; - annoDocs.push(annoDoc); - } - return annoDocs; - } - - startDrag = (e: PointerEvent) => { - console.log("start drag"); - e.preventDefault(); - document.removeEventListener("pointermove", this.startDrag); - document.removeEventListener("pointerup", this.endDrag); - let thisDoc = this.props.parent.Document; - let targetDoc = Docs.TextDocument(); - let annotationDocs = this.makeAnnotationDocuments(targetDoc); - targetDoc.annotations = new List(annotationDocs); - let dragData = new DragManager.AnnotationDragData(thisDoc, annotationDocs, targetDoc); - DragManager.StartAnnotationDrag(this._currentAnnotations, dragData, e.pageX, e.pageY, { - handlers: { - dragComplete: action(emptyFunction), - }, - hideSource: false - }); - e.stopPropagation(); - } - - endDrag = (e: PointerEvent): void => { - document.removeEventListener("pointermove", this.startDrag); - document.removeEventListener("pointerup", this.endDrag); - e.stopPropagation(); - } - - @action - onPointerDown = (e: React.PointerEvent) => { - if (e.shiftKey && e.button === 0) { - e.stopPropagation(); - - document.removeEventListener("pointermove", this.startDrag); - document.addEventListener("pointermove", this.startDrag); - document.removeEventListener("pointerup", this.endDrag); - document.addEventListener("pointerup", this.endDrag); - } - else if (e.button === 0) { - let target: any = e.target; - if (target && target.parentElement === this._textLayer.current) { - e.stopPropagation(); - } - else { - e.stopPropagation(); - runInAction(() => { - let current = this._textLayer.current; - if (current) { - let boundingRect = current.getBoundingClientRect(); - this._marqueeX = (e.clientX - boundingRect.left) * (current.offsetWidth / boundingRect.width); - this._marqueeY = (e.clientY - boundingRect.top) * (current.offsetHeight / boundingRect.height); - } - }); - this._marqueeing = true; - if (this._marquee.current) this._marquee.current.style.opacity = "0.2"; - } - document.removeEventListener("pointermove", this.onPointerMove); - document.addEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); - document.addEventListener("pointerup", this.onPointerUp); - if (!e.ctrlKey) { - for (let anno of this._currentAnnotations) { - anno.remove(); - } - } - } - } - - @action - onPointerMove = (e: PointerEvent) => { - let target: any = e.target; - if (this._marqueeing) { - let current = this._textLayer.current; - if (current) { - let boundingRect = current.getBoundingClientRect(); - this._marqueeWidth = (e.clientX - boundingRect.left) * (current.offsetWidth / boundingRect.width) - this._marqueeX; - this._marqueeHeight = (e.clientY - boundingRect.top) * (current.offsetHeight / boundingRect.height) - this._marqueeY; - if (this._marquee.current && this._curly.current) { - if (this._marqueeWidth > 100 && this._marqueeHeight > 100) { - this._marquee.current.style.background = "red"; - this._curly.current.style.opacity = "0"; - } - else { - this._marquee.current.style.background = "transparent"; - this._curly.current.style.opacity = "1"; - } - - let ratio = this._marqueeWidth / this._marqueeHeight; - if (ratio > 1.5) { - // vertical - this._rotate = "rotate(90deg) scale(1, 2)"; - } - else if (ratio < 0.5) { - // horizontal - this._rotate = "scale(2, 1)"; - } - else { - // diagonal - this._rotate = "rotate(45deg) scale(1.5, 1.5)"; - } - } - } - e.stopPropagation(); - e.preventDefault(); - } - else if (target && target.parentElement === this._textLayer.current) { - e.stopPropagation(); - } - } - - startAnnotation = (e: DragEvent) => { - console.log("drag starting"); - } - - pointerDownCancel = (e: PointerEvent) => { - e.stopPropagation(); - } - - @action - onPointerUp = (e: PointerEvent) => { - if (this._marqueeing) { - this._marqueeing = false; - if (this._marquee.current) { - let copy = document.createElement("div"); - copy.style.left = this._marquee.current.style.left; - copy.style.top = this._marquee.current.style.top; - copy.style.width = this._marquee.current.style.width; - copy.style.height = this._marquee.current.style.height; - copy.style.opacity = this._marquee.current.style.opacity; - copy.className = this._marquee.current.className; - if (this._annotationLayer.current) { - this._annotationLayer.current.append(copy); - this._currentAnnotations.push(copy); - } - this._marquee.current.style.opacity = "0"; - } - - this._marqueeHeight = this._marqueeWidth = 0; - } - else { - let sel = window.getSelection(); - // if selecting over a range of things - if (sel && sel.type === "Range") { - let clientRects = sel.getRangeAt(0).getClientRects(); - if (this._textLayer.current) { - let boundingRect = this._textLayer.current.getBoundingClientRect(); - for (let i = 0; i < clientRects.length; i++) { - let rect = clientRects.item(i); - if (rect) { - let annoBox = document.createElement("div"); - annoBox.className = "pdfViewer-annotationBox"; - // transforms the positions from screen onto the pdf div - annoBox.style.top = ((rect.top - boundingRect.top) * (this._textLayer.current.offsetHeight / boundingRect.height)).toString(); - annoBox.style.left = ((rect.left - boundingRect.left) * (this._textLayer.current.offsetWidth / boundingRect.width)).toString(); - annoBox.style.width = (rect.width * this._textLayer.current.offsetWidth / boundingRect.width).toString(); - annoBox.style.height = (rect.height * this._textLayer.current.offsetHeight / boundingRect.height).toString(); - annoBox.ondragstart = this.startAnnotation; - annoBox.onpointerdown = this.pointerDownCancel; - if (this._annotationLayer.current) this._annotationLayer.current.append(annoBox); - this._currentAnnotations.push(annoBox); - } - } - } - if (sel.empty) { // Chrome - sel.empty(); - } else if (sel.removeAllRanges) { // Firefox - sel.removeAllRanges(); - } - } - } - document.removeEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); - } - - annotationPointerDown = (e: React.PointerEvent) => { - console.log("annotation"); - } - - // imgVisible = () => { - // return this._marqueeWidth < 100 && this._marqueeHeight < 100 ? { opacity: "1" } : { opacity: "0" } - // } - - render() { - return ( -
-
- -
-
-
- -
-
-
-
- ); - } -} \ No newline at end of file diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx new file mode 100644 index 000000000..7cd72b27f --- /dev/null +++ b/src/client/views/pdf/Page.tsx @@ -0,0 +1,382 @@ +import { observer } from "mobx-react"; +import React = require("react"); +import { observable, action, runInAction } from "mobx"; +import * as Pdfjs from "pdfjs-dist"; +import { Opt, Doc, FieldResult, Field } from "../../../new_fields/Doc"; +import "./PDFViewer.scss"; +import "pdfjs-dist/web/pdf_viewer.css"; +import { PDFBox } from "../nodes/PDFBox"; +import { DragManager } from "../../util/DragManager"; +import { Docs } from "../../documents/Documents"; +import { List } from "../../../new_fields/List"; +import { emptyFunction } from "../../../Utils"; +import { Cast, NumCast } from "../../../new_fields/Types"; +import { listSpec } from "../../../new_fields/Schema"; + +interface IPageProps { + pdf: Opt; + name: string; + numPages: number; + page: number; + pageLoaded: (index: number, page: Pdfjs.PDFPageViewport) => void; + parent: PDFBox; +} + +@observer +export default class Page extends React.Component { + @observable private _state: string = "N/A"; + @observable private _width: number = 0; + @observable private _height: number = 0; + @observable private _page: Opt; + @observable private _currPage: number = this.props.page + 1; + @observable private _marqueeX: number = 0; + @observable private _marqueeY: number = 0; + @observable private _marqueeWidth: number = 0; + @observable private _marqueeHeight: number = 0; + @observable private _rotate: string = ""; + @observable private _annotations: List = new List(); + + private _canvas: React.RefObject; + private _textLayer: React.RefObject; + private _annotationLayer: React.RefObject; + private _marquee: React.RefObject; + private _curly: React.RefObject; + private _currentAnnotations: HTMLDivElement[] = []; + private _marqueeing: boolean = false; + private _dragging: boolean = false; + + constructor(props: IPageProps) { + super(props); + this._canvas = React.createRef(); + this._textLayer = React.createRef(); + this._annotationLayer = React.createRef(); + this._marquee = React.createRef(); + this._curly = React.createRef(); + } + + componentDidMount() { + 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) => { + this._state = "rendering"; + this.renderPage(page); + } + ); + } + + @action + private renderPage = (page: Pdfjs.PDFPageProxy) => { + // lower scale = easier to read at small sizes, higher scale = easier to read at large sizes + let scale = 2; + let viewport = page.getViewport(scale); + let canvas = this._canvas.current; + let textLayer = this._textLayer.current; + if (canvas && textLayer) { + let ctx = canvas.getContext("2d"); + canvas.width = viewport.width; + this._width = viewport.width; + canvas.height = viewport.height; + this._height = viewport.height; + this.props.pageLoaded(this._currPage, viewport); + if (ctx) { + // renders the page onto the canvas context + page.render({ canvasContext: ctx, viewport: viewport }); + // renders text onto the text container + page.getTextContent().then((res: Pdfjs.TextContent) => { + //@ts-ignore + Pdfjs.renderTextLayer({ + textContent: res, + container: textLayer, + viewport: viewport + }); + }); + + this._page = page; + } + } + } + + /** + * @param targetDoc: Document that annotations are linked to + * This method makes the list of current annotations into documents linked to + * the parameter passed in. + */ + makeAnnotationDocuments = (targetDoc: Doc): Doc[] => { + let annoDocs: Doc[] = []; + for (let anno of this._currentAnnotations) { + let annoDoc = new Doc(); + annoDoc.x = anno.offsetLeft; + annoDoc.y = anno.offsetTop; + annoDoc.height = anno.offsetHeight; + annoDoc.width = anno.offsetWidth; + annoDoc.target = targetDoc; + annoDocs.push(annoDoc); + anno.remove(); + } + this._currentAnnotations = []; + return annoDocs; + } + + /** + * This is temporary for creating annotations from highlights. It will + * start a drag event and create or put the necessary info into the drag event. + */ + @action + startDrag = (e: PointerEvent) => { + // the first 5 lines is a hack to prevent text selection while dragging + e.preventDefault(); + e.stopPropagation(); + if (this._dragging) { + return; + } + this._dragging = true; + let thisDoc = this.props.parent.Document; + // document that this annotation is linked to + let targetDoc = Docs.TextDocument({ width: 200, height: 200, title: "New Annotation" }); + targetDoc.targetPage = this.props.page; + // creates annotation documents for current highlights + let annotationDocs = this.makeAnnotationDocuments(targetDoc); + let targetAnnotations = Cast(targetDoc.annotations, listSpec(Doc)); + if (targetAnnotations) { + targetAnnotations.push(...annotationDocs); + targetDoc.annotations = targetAnnotations; + } + // temporary code (currently broken ? 6/7/19) to get annotations to rerender on pdf + let thisAnnotations = Cast(this.props.parent.Document.annotations, listSpec(Doc)); + if (thisAnnotations) { + thisAnnotations.push(...annotationDocs); + this.props.parent.Document.annotations = thisAnnotations; + let temp = new List(thisAnnotations); + temp.push(...this._annotations); + this._annotations = temp; + } + // create dragData and star tdrag + let dragData = new DragManager.AnnotationDragData(thisDoc, annotationDocs, targetDoc); + if (this._textLayer.current) { + DragManager.StartAnnotationDrag([this._textLayer.current], dragData, e.pageX, e.pageY, { + handlers: { + dragComplete: action(emptyFunction), + }, + hideSource: false + }); + } + } + + // cleans up events and boolean + endDrag = (e: PointerEvent): void => { + document.removeEventListener("pointermove", this.startDrag); + document.removeEventListener("pointerup", this.endDrag); + this._dragging = false; + e.stopPropagation(); + } + + @action + onPointerDown = (e: React.PointerEvent) => { + // if alt+left click, drag and annotate + if (e.altKey && e.button === 0) { + e.stopPropagation(); + + document.removeEventListener("pointermove", this.startDrag); + document.addEventListener("pointermove", this.startDrag); + document.removeEventListener("pointerup", this.endDrag); + document.addEventListener("pointerup", this.endDrag); + } + else if (e.button === 0) { + let target: any = e.target; + if (target && target.parentElement === this._textLayer.current) { + e.stopPropagation(); + } + else { + e.stopPropagation(); + // set marquee x and y positions to the spatially transformed position + let current = this._textLayer.current; + if (current) { + let boundingRect = current.getBoundingClientRect(); + this._marqueeX = (e.clientX - boundingRect.left) * (current.offsetWidth / boundingRect.width); + this._marqueeY = (e.clientY - boundingRect.top) * (current.offsetHeight / boundingRect.height); + } + this._marqueeing = true; + if (this._marquee.current) this._marquee.current.style.opacity = "0.2"; + } + document.removeEventListener("pointermove", this.onPointerMove); + document.addEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointerup", this.onPointerUp); + if (!e.ctrlKey) { + for (let anno of this._currentAnnotations) { + anno.remove(); + } + this._currentAnnotations = []; + } + } + } + + @action + onPointerMove = (e: PointerEvent) => { + let target: any = e.target; + if (this._marqueeing) { + let current = this._textLayer.current; + if (current) { + let boundingRect = current.getBoundingClientRect(); + this._marqueeWidth = (e.clientX - boundingRect.left) * (current.offsetWidth / boundingRect.width) - this._marqueeX; + this._marqueeHeight = (e.clientY - boundingRect.top) * (current.offsetHeight / boundingRect.height) - this._marqueeY; + if (this._marquee.current && this._curly.current) { + if (this._marqueeWidth > 100 && this._marqueeHeight > 100) { + this._marquee.current.style.background = "red"; + this._curly.current.style.opacity = "0"; + } + else { + this._marquee.current.style.background = "transparent"; + this._curly.current.style.opacity = "1"; + } + + let ratio = this._marqueeWidth / this._marqueeHeight; + if (ratio > 1.5) { + // vertical + this._rotate = "rotate(90deg) scale(1, 2)"; + } + else if (ratio < 0.5) { + // horizontal + this._rotate = "scale(2, 1)"; + } + else { + // diagonal + this._rotate = "rotate(45deg) scale(1.5, 1.5)"; + } + } + } + e.stopPropagation(); + e.preventDefault(); + } + else if (target && target.parentElement === this._textLayer.current) { + e.stopPropagation(); + } + } + + startAnnotation = () => { + console.log("drag starting"); + } + + pointerDownCancel = (e: PointerEvent) => { + e.stopPropagation(); + } + + @action + onPointerUp = () => { + if (this._marqueeing) { + this._marqueeing = false; + if (this._marquee.current) { + let copy = document.createElement("div"); + copy.style.left = this._marquee.current.style.left; + copy.style.top = this._marquee.current.style.top; + copy.style.width = this._marquee.current.style.width; + copy.style.height = this._marquee.current.style.height; + copy.style.opacity = this._marquee.current.style.opacity; + copy.className = this._marquee.current.className; + if (this._annotationLayer.current) { + this._annotationLayer.current.append(copy); + this._currentAnnotations.push(copy); + } + this._marquee.current.style.opacity = "0"; + } + + this._marqueeHeight = this._marqueeWidth = 0; + } + else { + let sel = window.getSelection(); + // if selecting over a range of things + if (sel && sel.type === "Range") { + let clientRects = sel.getRangeAt(0).getClientRects(); + if (this._textLayer.current) { + let boundingRect = this._textLayer.current.getBoundingClientRect(); + for (let i = 0; i < clientRects.length; i++) { + let rect = clientRects.item(i); + if (rect) { + let annoBox = document.createElement("div"); + annoBox.className = "pdfViewer-annotationBox"; + // transforms the positions from screen onto the pdf div + annoBox.style.top = ((rect.top - boundingRect.top) * (this._textLayer.current.offsetHeight / boundingRect.height)).toString(); + annoBox.style.left = ((rect.left - boundingRect.left) * (this._textLayer.current.offsetWidth / boundingRect.width)).toString(); + annoBox.style.width = (rect.width * this._textLayer.current.offsetWidth / boundingRect.width).toString(); + annoBox.style.height = (rect.height * this._textLayer.current.offsetHeight / boundingRect.height).toString(); + annoBox.ondragstart = this.startAnnotation; + annoBox.onpointerdown = this.pointerDownCancel; + if (this._annotationLayer.current) this._annotationLayer.current.append(annoBox); + this._currentAnnotations.push(annoBox); + } + } + } + if (sel.empty) { // Chrome + sel.empty(); + } else if (sel.removeAllRanges) { // Firefox + sel.removeAllRanges(); + } + } + } + document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + } + + renderAnnotation = (anno: Doc | undefined): HTMLDivElement => { + let annoBox = document.createElement("div"); + if (anno) { + annoBox.className = "pdfViewer-annotationBox"; + // transforms the positions from screen onto the pdf div + annoBox.style.top = NumCast(anno.x).toString(); + annoBox.style.left = NumCast(anno.y).toString(); + annoBox.style.width = NumCast(anno.width).toString(); + annoBox.style.height = NumCast(anno.height).toString() + annoBox.onpointerdown = this.pointerDownCancel; + } + return annoBox; + } + + annotationPointerDown = () => { + console.log("annotation"); + } + + // imgVisible = () => { + // return this._marqueeWidth < 100 && this._marqueeHeight < 100 ? { opacity: "1" } : { opacity: "0" } + // } + + render() { + let annotations = this._annotations; + return ( +
+
+ +
+
+
+ +
+ {annotations.map(anno => this.renderAnnotation(anno instanceof Doc ? anno : undefined))} +
+
+
+ ); + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 9ec4a529dc886acca8f147cfe913e60f938f3bda Mon Sep 17 00:00:00 2001 From: yipstanley Date: Wed, 12 Jun 2019 14:35:24 -0400 Subject: reverse annotating --- src/client/util/DragManager.ts | 6 +- src/client/views/pdf/PDFViewer.tsx | 112 ++++++++++++++++++++++++++++++------- src/client/views/pdf/Page.tsx | 27 ++++++--- 3 files changed, 116 insertions(+), 29 deletions(-) (limited to 'src/client/util/DragManager.ts') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index e92ed9b4a..2ffb77e44 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -154,14 +154,14 @@ export namespace DragManager { } export class AnnotationDragData { - constructor(dragDoc: Doc, annotationDocs: Doc[], dropDoc: Doc) { + constructor(dragDoc: Doc, annotationDoc: Doc, dropDoc: Doc) { this.dragDocument = dragDoc; this.dropDocument = dropDoc; - this.annotationDocuments = annotationDocs; + this.annotationDocument = annotationDoc; this.xOffset = this.yOffset = 0; } dragDocument: Doc; - annotationDocuments: Doc[]; + annotationDocument: Doc; dropDocument: Doc; xOffset: number; yOffset: number; diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 6823f640e..bfd0e036f 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -7,7 +7,7 @@ import "./PDFViewer.scss"; import "pdfjs-dist/web/pdf_viewer.css"; import { PDFBox } from "../nodes/PDFBox"; import Page from "./Page"; -import { NumCast, Cast, BoolCast } from "../../../new_fields/Types"; +import { NumCast, Cast, BoolCast, StrCast } from "../../../new_fields/Types"; import { Id } from "../../../new_fields/FieldSymbols"; import { DocUtils, Docs } from "../../documents/Documents"; import { DocumentManager } from "../../util/DocumentManager"; @@ -18,6 +18,8 @@ import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocum import { Transform } from "../../util/Transform"; import { emptyFunction, returnTrue, returnFalse } from "../../../Utils"; import { DocumentView } from "../nodes/DocumentView"; +import { DragManager } from "../../util/DragManager"; +import { Dictionary } from "typescript-collections"; interface IPDFViewerProps { url: string; @@ -83,12 +85,15 @@ class Viewer extends React.Component { @observable private _loaded: boolean = false; @observable private _pdf: Opt; @observable private _annotations: Doc[] = []; + @observable private _pointerEvents: "all" | "none" = "all"; + @observable private _savedAnnotations: Dictionary = new Dictionary(); private _pageBuffer: number = 1; private _annotationLayer: React.RefObject; private _reactionDisposer?: IReactionDisposer; private _annotationReactionDisposer?: IReactionDisposer; private _pagesLoaded: number = 0; + private _dropDisposer?: DragManager.DragDropDisposer; constructor(props: IViewerProps) { super(props); @@ -96,6 +101,7 @@ class Viewer extends React.Component { this._annotationLayer = React.createRef(); } + @action componentDidMount = () => { let wasSelected = this.props.parent.props.isSelected(); // reaction for when document gets (de)selected @@ -105,10 +111,12 @@ class Viewer extends React.Component { // if deselected, render images in place of pdf if (wasSelected && !this.props.parent.props.isSelected()) { this.saveThumbnail(); + this._pointerEvents = "all"; } // if selected, render pdf else if (!wasSelected && this.props.parent.props.isSelected()) { this.renderPages(this.startIndex, this.endIndex, true); + this._pointerEvents = "none"; } wasSelected = this.props.parent.props.isSelected(); }, @@ -133,6 +141,57 @@ class Viewer extends React.Component { }, 1000); } + private mainCont = (div: HTMLDivElement | null) => { + if (this._dropDisposer) { + this._dropDisposer(); + } + if (div) { + this._dropDisposer = DragManager.MakeDropTarget(div, { + handlers: { drop: this.drop.bind(this) } + }); + } + } + + makeAnnotationDocuments = (sourceDoc: Doc): Doc => { + let annoDocs: Doc[] = []; + this._savedAnnotations.forEach((key: number, value: HTMLDivElement[]) => { + for (let anno of value) { + let annoDoc = new Doc(); + 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.page = key; + annoDoc.target = sourceDoc; + annoDoc.type = AnnotationTypes.Region; + annoDocs.push(annoDoc); + anno.remove(); + } + }); + + let annoDoc = new Doc(); + annoDoc.annotations = new List(annoDocs); + DocUtils.MakeLink(sourceDoc, annoDoc, `Annotation from ${StrCast(this.props.parent.Document.title)}`, "", StrCast(this.props.parent.Document.title)); + this._savedAnnotations.clear(); + return annoDoc; + } + + drop = async (e: Event, de: DragManager.DropEvent) => { + if (de.data instanceof DragManager.LinkDragData) { + let sourceDoc = de.data.linkSourceDocument; + let destDoc = this.makeAnnotationDocuments(sourceDoc); + let targetAnnotations = DocListCast(this.props.parent.Document.annotations); + if (targetAnnotations) { + targetAnnotations.push(destDoc); + this.props.parent.Document.annotations = new List(targetAnnotations); + } + else { + this.props.parent.Document.annotations = new List([destDoc]); + } + } + e.stopPropagation(); + } + componentWillUnmount = () => { if (this._reactionDisposer) { this._reactionDisposer(); @@ -219,6 +278,8 @@ class Viewer extends React.Component { parent={this.props.parent} renderAnnotations={this.renderAnnotations} makePin={this.createPinAnnotation} + sendAnnotations={this.receiveAnnotations} + receiveAnnotations={this.sendAnnotations} {...this.props} /> )); let arr = Array.from(Array(numPages).keys()).map(() => false); @@ -257,6 +318,8 @@ class Viewer extends React.Component { parent={this.props.parent} makePin={this.createPinAnnotation} renderAnnotations={this.renderAnnotations} + sendAnnotations={this.receiveAnnotations} + receiveAnnotations={this.sendAnnotations} {...this.props} /> ); this._isPage[i] = true; @@ -269,6 +332,15 @@ class Viewer extends React.Component { return; } + @action + receiveAnnotations = (annotations: HTMLDivElement[], page: number) => { + this._savedAnnotations.setValue(page, annotations); + } + + sendAnnotations = (page: number): HTMLDivElement[] | undefined => { + return this._savedAnnotations.getValue(page); + } + createPinAnnotation = (x: number, y: number, page: number): void => { let targetDoc = Docs.TextDocument({ width: 100, height: 50, title: "New Pin Annotation" }); @@ -280,13 +352,15 @@ class Viewer extends React.Component { pinAnno.target = targetDoc; pinAnno.type = AnnotationTypes.Pin; // this._annotations.push(pinAnno); + let annoDoc = new Doc(); + annoDoc.annotations = new List([pinAnno]); let annotations = DocListCast(this.props.parent.Document.annotations); if (annotations && annotations.length) { - annotations.push(pinAnno); + annotations.push(annoDoc); this.props.parent.Document.annotations = new List(annotations); } else { - this.props.parent.Document.annotations = new List([pinAnno]); + this.props.parent.Document.annotations = new List([annoDoc]); } // let pinAnno = document.createElement("div"); // pinAnno.className = "pdfViewer-pinAnnotation"; @@ -349,20 +423,20 @@ class Viewer extends React.Component { return counter; } - renderAnnotation = (anno: Doc): JSX.Element => { - let type = NumCast(anno.type); - switch (type) { - case AnnotationTypes.Pin: - return ; - case AnnotationTypes.Region: - return ; - default: - return
; - } - } - - onDrop = (e: React.DragEvent) => { - console.log("Dropped!"); + renderAnnotation = (anno: Doc): JSX.Element[] => { + let annotationDocs = DocListCast(anno.annotations); + let res = annotationDocs.map(a => { + let type = NumCast(a.type); + switch (type) { + case AnnotationTypes.Pin: + return ; + case AnnotationTypes.Region: + return ; + default: + return
; + } + }); + return res; } // ScreenToLocalTransform = (): Transform => { @@ -380,11 +454,11 @@ class Viewer extends React.Component { render() { trace(); return ( -
+
{this._visibleElements}
-
+
{this._annotations.map(anno => this.renderAnnotation(anno))}
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx index 73a7a93a0..908804605 100644 --- a/src/client/views/pdf/Page.tsx +++ b/src/client/views/pdf/Page.tsx @@ -24,6 +24,8 @@ interface IPageProps { parent: PDFBox; renderAnnotations: (annotations: Doc[], removeOld: boolean) => void; makePin: (x: number, y: number, page: number) => void; + sendAnnotations: (annotations: HTMLDivElement[], page: number) => void; + receiveAnnotations: (page: number) => HTMLDivElement[] | undefined; } @observer @@ -61,11 +63,19 @@ export default class Page extends React.Component { componentDidMount = (): void => { if (this.props.pdf) { this.update(this.props.pdf); + } + let received = this.props.receiveAnnotations(this.props.page); + this._currentAnnotations = received ? received : []; + if (this._annotationLayer.current) { + this._annotationLayer.current.append(...this._currentAnnotations); } } componentWillUnmount = (): void => { + console.log(this._currentAnnotations); + this.props.sendAnnotations(this._currentAnnotations, this.props.page); + if (this._reactionDisposer) { this._reactionDisposer(); } @@ -134,8 +144,9 @@ export default class Page extends React.Component { * This method makes the list of current annotations into documents linked to * the parameter passed in. */ - makeAnnotationDocuments = (targetDoc: Doc): Doc[] => { + makeAnnotationDocuments = (targetDoc: Doc): Doc => { let annoDocs: Doc[] = []; + for (let anno of this._currentAnnotations) { let annoDoc = new Doc(); annoDoc.x = anno.offsetLeft; @@ -146,11 +157,13 @@ export default class Page extends React.Component { annoDoc.target = targetDoc; annoDoc.type = AnnotationTypes.Region; annoDocs.push(annoDoc); - DocUtils.MakeLink(annoDoc, targetDoc, `Annotation from ${StrCast(this.props.parent.Document.title)}`, "", StrCast(this.props.parent.Document.title)); anno.remove(); } + let annoDoc = new Doc(); + annoDoc.annotations = new List(annoDocs); + DocUtils.MakeLink(annoDoc, targetDoc, `Annotation from ${StrCast(this.props.parent.Document.title)}`, "", StrCast(this.props.parent.Document.title)); this._currentAnnotations = []; - return annoDocs; + return annoDoc; } /** @@ -171,17 +184,17 @@ export default class Page extends React.Component { let targetDoc = Docs.TextDocument({ width: 200, height: 200, title: "New Annotation" }); targetDoc.targetPage = this.props.page; // creates annotation documents for current highlights - let annotationDocs = this.makeAnnotationDocuments(targetDoc); + let annotationDoc = this.makeAnnotationDocuments(targetDoc); let targetAnnotations = DocListCast(this.props.parent.Document.annotations); if (targetAnnotations) { - targetAnnotations.push(...annotationDocs); + targetAnnotations.push(annotationDoc); this.props.parent.Document.annotations = new List(targetAnnotations); } else { - this.props.parent.Document.annotations = new List(annotationDocs); + this.props.parent.Document.annotations = new List([annotationDoc]); } // create dragData and star tdrag - let dragData = new DragManager.AnnotationDragData(thisDoc, annotationDocs, targetDoc); + let dragData = new DragManager.AnnotationDragData(thisDoc, annotationDoc, targetDoc); if (this._textLayer.current) { DragManager.StartAnnotationDrag([this._textLayer.current], dragData, e.pageX, e.pageY, { handlers: { -- cgit v1.2.3-70-g09d2 From b681e584f52a9ffe03c9d93b199b6487e5d1a5e5 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 15 Jun 2019 23:07:45 -0400 Subject: fixed dragging within treeview. --- src/client/util/DragManager.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'src/client/util/DragManager.ts') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index ab00fabe1..88027a601 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -261,6 +261,7 @@ export namespace DragManager { // } // } let set = dragElement.getElementsByTagName('*'); + if (dragElement.hasAttribute("style")) (dragElement as any).style.pointerEvents = "none"; for (let i = 0; i < set.length; i++) if (set[i].hasAttribute("style")) { let s = set[i]; -- cgit v1.2.3-70-g09d2 From 13e301dea2f537b67b338cc6a98d3f3b5a8e1f36 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 18 Jun 2019 20:58:32 -0400 Subject: Fixed linter errors --- src/client/northstar/dash-nodes/HistogramBox.tsx | 3 +-- src/client/util/DocumentManager.ts | 6 +++--- src/client/util/DragManager.ts | 4 +++- src/client/util/RichTextSchema.tsx | 10 +++++----- src/client/util/TooltipTextMenu.tsx | 2 +- src/client/views/ContextMenu.tsx | 4 ++-- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/MainOverlayTextBox.tsx | 2 +- src/client/views/MainView.tsx | 7 ++++--- src/client/views/PresentationView.tsx | 4 ++-- src/client/views/collections/CollectionBaseView.tsx | 2 +- src/client/views/collections/CollectionDockingView.tsx | 5 +++-- src/client/views/collections/CollectionPDFView.tsx | 2 +- src/client/views/collections/CollectionSchemaView.tsx | 11 ++++++----- src/client/views/collections/CollectionStackingView.tsx | 4 ++-- src/client/views/collections/CollectionTreeView.tsx | 10 +++++----- .../collectionFreeForm/CollectionFreeFormLinksView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../views/collections/collectionFreeForm/MarqueeView.tsx | 2 +- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 12 ++++++------ src/client/views/nodes/FormattedTextBox.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 3 ++- src/client/views/pdf/PDFAnnotationLayer.tsx | 2 +- src/client/views/pdf/PDFMenu.tsx | 2 +- src/client/views/pdf/PDFViewer.tsx | 4 ++-- src/server/index.ts | 2 +- 27 files changed, 59 insertions(+), 54 deletions(-) (limited to 'src/client/util/DragManager.ts') diff --git a/src/client/northstar/dash-nodes/HistogramBox.tsx b/src/client/northstar/dash-nodes/HistogramBox.tsx index d7732ee86..a60eaea85 100644 --- a/src/client/northstar/dash-nodes/HistogramBox.tsx +++ b/src/client/northstar/dash-nodes/HistogramBox.tsx @@ -125,8 +125,7 @@ export class HistogramBox extends React.Component { let mapped = brushingDocs.map((brush, i) => { brush.backgroundColor = StyleConstants.BRUSH_COLORS[i % StyleConstants.BRUSH_COLORS.length]; let brushed = DocListCast(brush.brushingDocs); - if (!brushed.length) - return null; + if (!brushed.length) return null; return { l: brush, b: brushed[0][Id] === proto[Id] ? brushed[1] : brushed[0] }; }); runInAction(() => this.HistoOp.BrushLinks.splice(0, this.HistoOp.BrushLinks.length, ...mapped.filter(m => m) as { l: Doc, b: Doc }[])); diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index ff0c1560b..862395d74 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -35,9 +35,9 @@ export class DocumentManager { let toReturn: DocumentView | null = null; let passes = preferredCollection ? [preferredCollection, undefined] : [undefined]; - for (let i = 0; i < passes.length; i++) { + for (let pass of passes) { DocumentManager.Instance.DocumentViews.map(view => { - if (view.props.Document[Id] === id && (!passes[i] || view.props.ContainingCollectionView === preferredCollection)) { + if (view.props.Document[Id] === id && (!pass || view.props.ContainingCollectionView === preferredCollection)) { toReturn = view; return; } @@ -45,7 +45,7 @@ export class DocumentManager { if (!toReturn) { DocumentManager.Instance.DocumentViews.map(view => { let doc = view.props.Document.proto; - if (doc && doc[Id] === id && (!passes[i] || view.props.ContainingCollectionView === preferredCollection)) { + if (doc && doc[Id] === id && (!pass || view.props.ContainingCollectionView === preferredCollection)) { toReturn = view; } }); diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 89566e777..c3c92daa5 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -282,11 +282,13 @@ export namespace DragManager { // } let set = dragElement.getElementsByTagName('*'); if (dragElement.hasAttribute("style")) (dragElement as any).style.pointerEvents = "none"; - for (let i = 0; i < set.length; i++) + // tslint:disable-next-line: prefer-for-of + for (let i = 0; i < set.length; i++) { if (set[i].hasAttribute("style")) { let s = set[i]; (s as any).style.pointerEvents = "none"; } + } dragDiv.appendChild(dragElement); diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index e1e595925..943cdb4d1 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -156,12 +156,12 @@ export const nodes: { [index: string]: NodeSpec } = { title: dom.getAttribute("title"), alt: dom.getAttribute("alt"), width: Math.min(100, Number(dom.getAttribute("width"))), - } + }; } }], toDOM(node) { - const attrs = { style: `width: ${node.attrs.width}` } - return ["video", { ...node.attrs, ...attrs }] + const attrs = { style: `width: ${node.attrs.width}` }; + return ["video", { ...node.attrs, ...attrs }]; } }, @@ -285,7 +285,7 @@ export const marks: { [index: string]: MarkSpec } = { toDOM() { return ['span', { style: 'color: blue' - }] + }]; } }, @@ -536,4 +536,4 @@ schema.nodeFromJSON = (json: any) => { node.attrs.oldtext = Slice.fromJSON(schema, node.attrs.oldtextslice); } return node; -} \ No newline at end of file +}; \ No newline at end of file diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 0a61b7e7d..f2559db74 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -256,7 +256,7 @@ export class TooltipTextMenu { starButton.onclick = () => { let state = this.view.state; this.insertStar(state, this.view.dispatch); - } + }; this.tooltip.appendChild(starButton); } diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index da374455e..eb1937683 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -1,8 +1,8 @@ import React = require("react"); import { ContextMenuItem, ContextMenuProps } from "./ContextMenuItem"; import { observable, action } from "mobx"; -import { observer } from "mobx-react" -import "./ContextMenu.scss" +import { observer } from "mobx-react"; +import "./ContextMenu.scss"; import { library } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faSearch, faCircle } from '@fortawesome/free-solid-svg-icons'; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index ceca940b6..e60f8c86c 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -466,7 +466,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> SelectionManager.SelectedDocuments().forEach(element => { const rect = element.ContentDiv ? element.ContentDiv.getBoundingClientRect() : new DOMRect(); - if (rect.width !== 0 && (dX != 0 || dY != 0 || dW != 0 || dH != 0)) { + if (rect.width !== 0 && (dX !== 0 || dY !== 0 || dW !== 0 || dH !== 0)) { let doc = PositionDocument(element.props.Document); let nwidth = doc.nativeWidth || 0; let nheight = doc.nativeHeight || 0; diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index 0de880175..b4ad5f4d7 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -40,7 +40,7 @@ export class MainOverlayTextBox extends React.Component this.TextDoc = box.props.Document; let sxf = Utils.GetScreenTransform(box ? box.CurrentDiv : undefined); let xf = () => { box.props.ScreenToLocalTransform(); return new Transform(-sxf.translateX, -sxf.translateY, 1 / sxf.scale); }; - this.setTextDoc(box.props.fieldKey, box.CurrentDiv, xf, BoolCast(box.props.Document.autoHeight, false) || box.props.height === "min-content") + this.setTextDoc(box.props.fieldKey, box.CurrentDiv, xf, BoolCast(box.props.Document.autoHeight, false) || box.props.height === "min-content"); } else { this.TextDoc = undefined; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index fd76cbbd3..7f979cd3b 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -237,10 +237,11 @@ export class MainView extends React.Component { } onColorClick = (e: React.MouseEvent) => { - let target = (e.nativeEvent! as any).path[0]; - let parent = (e.nativeEvent! as any).path[1]; - if (target.localName === "input" || parent.localName === "span") + let target = (e.nativeEvent as any).path[0]; + let parent = (e.nativeEvent as any).path[1]; + if (target.localName === "input" || parent.localName === "span") { e.stopPropagation(); + } } diff --git a/src/client/views/PresentationView.tsx b/src/client/views/PresentationView.tsx index d2d41a4ba..1dacbb663 100644 --- a/src/client/views/PresentationView.tsx +++ b/src/client/views/PresentationView.tsx @@ -40,8 +40,8 @@ class PresentationViewList extends React.Component { //this doc is selected className += " presentationView-selected"; } - let onEnter = (e: React.PointerEvent) => { document.libraryBrush = true; } - let onLeave = (e: React.PointerEvent) => { document.libraryBrush = false; } + let onEnter = (e: React.PointerEvent) => { document.libraryBrush = true; }; + let onLeave = (e: React.PointerEvent) => { document.libraryBrush = false; }; return (
{ @action.bound removeDocument(doc: Doc): boolean { - let docView = DocumentManager.Instance.getDocumentView(doc, this.props.ContainingCollectionView) + let docView = DocumentManager.Instance.getDocumentView(doc, this.props.ContainingCollectionView); docView && SelectionManager.DeselectDoc(docView); const props = this.props; //TODO This won't create the field if it doesn't already exist diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index f2b3528b8..5beb89315 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -347,7 +347,7 @@ export class CollectionDockingView extends React.Component CollectionDockingView.Instance.AddTab(stack, doc)} />, upDiv); tab.reactComponents = [upDiv]; tab.element.append(upDiv); @@ -432,8 +432,9 @@ export class DockedFrameRenderer extends React.Component { @observable private _document: Opt; get _stack(): any { let parent = (this.props as any).glContainer.parent.parent; - if (this._document && this._document.excludeFromLibrary && parent.parent && parent.parent.contentItems.length > 1) + if (this._document && this._document.excludeFromLibrary && parent.parent && parent.parent.contentItems.length > 1) { return parent.parent.contentItems[1]; + } return parent; } constructor(props: any) { diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx index b62d3f7bb..b2d016934 100644 --- a/src/client/views/collections/CollectionPDFView.tsx +++ b/src/client/views/collections/CollectionPDFView.tsx @@ -40,7 +40,7 @@ export class CollectionPDFView extends React.Component { // console.log(this.props.Document[HeightSym]()); }, { fireImmediately: true } - ) + ); } public static LayoutString(fieldKey: string = "data") { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 14a7d19d0..faea8d44d 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -87,8 +87,9 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { let columnDocs = DocListCast(schemaDoc.data); if (columnDocs) { let ddoc = columnDocs.find(doc => doc.title === columnName); - if (ddoc) + if (ddoc) { return ddoc; + } } } return this.props.Document; @@ -285,7 +286,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { } getPreviewTransform = (): Transform => this.props.ScreenToLocalTransform().translate( - - this.borderWidth - this.DIVIDER_WIDTH - this.tableWidth, - this.borderWidth); + - this.borderWidth - this.DIVIDER_WIDTH - this.tableWidth, - this.borderWidth) get documentKeysCheckList() { @@ -334,7 +335,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { columns={this.tableColumns} column={{ ...ReactTableDefaults.column, Cell: this.renderCell, }} getTrProps={this.getTrProps} - /> + />; } @computed @@ -360,7 +361,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { addDocTab={this.props.addDocTab} setPreviewScript={this.setPreviewScript} previewScript={this.previewScript} - /> + />; } @action setPreviewScript = (script: string) => { @@ -409,7 +410,7 @@ export class CollectionSchemaPreview extends React.Component this.nativeWidth * this.contentScaling(); private PanelHeight = () => this.nativeHeight * this.contentScaling(); - private getTransform = () => this.props.getTransform().translate(-this.centeringOffset, 0).scale(1 / this.contentScaling()) + private getTransform = () => this.props.getTransform().translate(-this.centeringOffset, 0).scale(1 / this.contentScaling()); get centeringOffset() { return (this.props.width() - this.nativeWidth * this.contentScaling()) / 2; } @action onPreviewScriptChange = (e: React.ChangeEvent) => { diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index e1ac3505b..f5ad4ee95 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -101,7 +101,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { let childFocus = (doc: Doc) => { doc.libraryBrush = true; this.props.focus(this.props.Document); // just focus on this collection, not the underlying document because the API doesn't support adding an offset to focus on and we can't pan zoom our contents to be centered. - } + }; return (
doc) { whenActiveChanged={this.props.whenActiveChanged} />
); - }) + }); } onContextMenu = (e: React.MouseEvent): void => { if (!e.isPropagationStopped() && this.props.Document[Id] !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index b13694e9d..3e495b734 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -67,8 +67,8 @@ class TreeView extends React.Component { @undoBatch delete = () => this.props.deleteDoc(this.props.document); @undoBatch openRight = async () => this.props.addDocTab(this.props.document, "openRight"); - @action onMouseEnter = () => { this._isOver = true; } - @action onMouseLeave = () => { this._isOver = false; } + @action onMouseEnter = () => { this._isOver = true; }; + @action onMouseLeave = () => { this._isOver = false; }; onPointerEnter = (e: React.PointerEvent): void => { this.props.active() && (this.props.document.libraryBrush = true); @@ -89,8 +89,8 @@ class TreeView extends React.Component { let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); let before = x[1] < bounds[1]; let inside = x[0] > bounds[0] + 75 || (!before && this._bulletType === BulletType.Collapsible); - this._header!.current!.className = "treeViewItem-header" - if (inside && this._bulletType != BulletType.List) this._header!.current!.className += " treeViewItem-header-inside"; + this._header!.current!.className = "treeViewItem-header"; + if (inside && this._bulletType !== BulletType.List) this._header!.current!.className += " treeViewItem-header-inside"; else if (before) this._header!.current!.className += " treeViewItem-header-above"; else if (!before) this._header!.current!.className += " treeViewItem-header-below"; e.stopPropagation(); @@ -192,7 +192,7 @@ class TreeView extends React.Component { if (inside) { let docList = Cast(this.props.document.data, listSpec(Doc)); if (docList !== undefined) { - addDoc = (doc: Doc) => { docList && docList.push(doc); return true; } + addDoc = (doc: Doc) => { docList && docList.push(doc); return true; }; } } let added = false; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx index c4dd534ed..be75c6c5c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx @@ -109,7 +109,7 @@ export class CollectionFreeFormLinksView extends React.Component [ , ...this.views - ]; + ] render() { const containerName = `collectionfreeformview${this.isAnnotationOverlay ? "-overlay" : "-container"}`; const easing = () => this.props.Document.panTransformType === "Ease"; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index dedcc3172..05dc6f534 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -321,7 +321,7 @@ export class MarqueeView extends React.Component summary.imageSummary = imageSummary; this.props.addDocument(imageSummary, false); } - }) + }); newCollection.proto!.summaryDoc = summary; selected = [newCollection]; newCollection.x = bounds.left + bounds.width; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index f6b1c62ee..858959d81 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -48,7 +48,7 @@ export class CollectionFreeFormDocumentView extends DocComponent this.props.PanelHeight(); getTransform = (): Transform => this.props.ScreenToLocalTransform() .translate(-this.X, -this.Y) - .scale(1 / this.contentScaling()).scale(1 / this.zoom); + .scale(1 / this.contentScaling()).scale(1 / this.zoom) animateBetweenIcon = (icon: number[], stime: number, maximizing: boolean) => { this.props.bringToFront(this.props.Document); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7c058d91c..4992669df 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -168,8 +168,8 @@ export class DocumentView extends DocComponent(Docu public static animateBetweenIconFunc = (doc: Doc, width: number, height: number, stime: number, maximizing: boolean, cb?: (progress: number) => void) => { setTimeout(() => { let now = Date.now(); - let progress = now < stime + 200 ? Math.min(1, (now - stime) / 200) : 1 - doc.width = progress === 1 ? width : maximizing ? 25 + (width - 25) * progress : width + (25 - width) * progress + let progress = now < stime + 200 ? Math.min(1, (now - stime) / 200) : 1; + doc.width = progress === 1 ? width : maximizing ? 25 + (width - 25) * progress : width + (25 - width) * progress; doc.height = progress === 1 ? height : maximizing ? 25 + (height - 25) * progress : height + (25 - height) * progress; cb && cb(progress); if (now < stime + 200) { @@ -229,7 +229,7 @@ export class DocumentView extends DocComponent(Docu if (minimizedDoc) { let scrpt = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint( NumCast(minimizedDoc.x) - NumCast(this.Document.x), NumCast(minimizedDoc.y) - NumCast(this.Document.y)); - this.collapseTargetsToPoint(scrpt, await DocListCastAsync(minimizedDoc.maximizedDocs)) + this.collapseTargetsToPoint(scrpt, await DocListCastAsync(minimizedDoc.maximizedDocs)); } } @@ -372,8 +372,8 @@ export class DocumentView extends DocComponent(Docu this._lastTap = Date.now(); } - deleteClicked = (): void => { this.props.removeDocument && this.props.removeDocument(this.props.Document); } - fieldsClicked = (): void => { this.props.addDocTab(Docs.KVPDocument(this.props.Document, { width: 300, height: 300 }), "onRight") }; + deleteClicked = (): void => { this.props.removeDocument && this.props.removeDocument(this.props.Document); }; + fieldsClicked = (): void => { this.props.addDocTab(Docs.KVPDocument(this.props.Document, { width: 300, height: 300 }), "onRight"); }; makeBtnClicked = (): void => { let doc = Doc.GetProto(this.props.Document); doc.isButton = !BoolCast(doc.isButton, false); @@ -527,7 +527,7 @@ export class DocumentView extends DocComponent(Docu onPointerLeave = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = false; }; isSelected = () => SelectionManager.IsSelected(this); - @action select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); } + @action select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); }; @computed get nativeWidth() { return this.Document.nativeWidth || 0; } @computed get nativeHeight() { return this.Document.nativeHeight || 0; } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 36d902c4f..df12f261b 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -161,7 +161,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe de.data.moveDocument(de.data.draggedDocuments[0], stackDoc, (doc) => { Cast(stackDoc.data, listSpec(Doc))!.push(doc); return true; - }) + }); } } } diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 6b8b64c5f..f208ce2ce 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -188,8 +188,9 @@ export class ImageBox extends DocComponent(ImageD } @action onError = () => { let timeout = this._curSuffix === "_s" ? this._smallRetryCount : this._curSuffix === "_m" ? this._mediumRetryCount : this._largeRetryCount; - if (timeout < 10) + if (timeout < 10) { setTimeout(this.retryPath, Math.min(10000, timeout * 5)); + } } _curSuffix = "_m"; render() { diff --git a/src/client/views/pdf/PDFAnnotationLayer.tsx b/src/client/views/pdf/PDFAnnotationLayer.tsx index e92dcacbf..1f49e0d2f 100644 --- a/src/client/views/pdf/PDFAnnotationLayer.tsx +++ b/src/client/views/pdf/PDFAnnotationLayer.tsx @@ -19,6 +19,6 @@ export class PDFAnnotationLayer extends React.Component {
- ) + ); } } \ No newline at end of file diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx index 7817e8c26..2ed891131 100644 --- a/src/client/views/pdf/PDFMenu.tsx +++ b/src/client/views/pdf/PDFMenu.tsx @@ -162,6 +162,6 @@ export default class PDFMenu extends React.Component {
- ) + ); } } \ No newline at end of file diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 69372f43b..8c0aaea00 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -198,7 +198,7 @@ class Viewer extends React.Component { { @action getPageImage = async (page: number) => { let handleError = () => this.getRenderedPage(page); - if (this._isPage[page] != "image") { + if (this._isPage[page] !== "image") { this._isPage[page] = "image"; const address = this.props.url; let res = JSON.parse(await rp.get(DocServer.prepend(`/thumbnail${address.substring("files/".length, address.length - ".pdf".length)}-${page + 1}.PNG`))); diff --git a/src/server/index.ts b/src/server/index.ts index 7ef542b01..2901f61ed 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -172,7 +172,7 @@ function LoadPage(file: string, pageNumber: number, res: Response) { canvasContext: canvasAndContext.context, viewport: viewport, canvasFactory: factory - } + }; console.log("read " + pageNumber); page.render(renderContext).promise -- cgit v1.2.3-70-g09d2