From ffecdb309695ac9030626346b21013bcbf2e7731 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sat, 18 May 2019 17:06:18 -0400 Subject: server debugging --- src/client/views/collections/CollectionBaseView.tsx | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 31bdf213e..8687442a5 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -39,6 +39,9 @@ export class CollectionBaseView extends React.Component { get collectionViewType(): CollectionViewType | undefined { let Document = this.props.Document; let viewField = Cast(Document.viewType, "number"); + if (viewField === CollectionViewType.Freeform) { + return CollectionViewType.Tree; + } if (viewField !== undefined) { return viewField; } else { -- cgit v1.2.3-70-g09d2 From 5b4ffd962d7f89a40edcb3409b5904a752f13fbb Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sat, 18 May 2019 17:16:30 -0400 Subject: More debugging --- src/client/views/collections/CollectionBaseView.tsx | 4 ++++ src/client/views/collections/CollectionView.tsx | 1 + 2 files changed, 5 insertions(+) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 8687442a5..73eb1fbbc 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -16,6 +16,7 @@ export enum CollectionViewType { Schema, Docking, Tree, + RealFreeform } export interface CollectionRenderProps { @@ -42,6 +43,9 @@ export class CollectionBaseView extends React.Component { if (viewField === CollectionViewType.Freeform) { return CollectionViewType.Tree; } + if (viewField === CollectionViewType.RealFreeform) { + return CollectionViewType.Freeform; + } if (viewField !== undefined) { return viewField; } else { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 3d9b4990a..33427a991 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -41,6 +41,7 @@ export class CollectionView extends React.Component { onContextMenu = (e: React.MouseEvent): void => { if (!this.isAnnotationOverlay && !e.isPropagationStopped() && this.props.Document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 ContextMenu.Instance.addItem({ description: "Freeform", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Freeform), icon: "project-diagram" }); + ContextMenu.Instance.addItem({ description: "Freeform2", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.RealFreeform), icon: "project-diagram" }); ContextMenu.Instance.addItem({ description: "Schema", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Schema), icon: "project-diagram" }); ContextMenu.Instance.addItem({ description: "Treeview", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Tree), icon: "tree" }); } -- cgit v1.2.3-70-g09d2 From 130b5c55f954a011e91355c79ade4b9f91bd84e9 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sat, 18 May 2019 18:17:39 -0400 Subject: clamped scale and reverted safe mode --- src/client/views/collections/CollectionBaseView.tsx | 14 +++++++------- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 73eb1fbbc..2da8c4e40 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -16,7 +16,7 @@ export enum CollectionViewType { Schema, Docking, Tree, - RealFreeform + // RealFreeform } export interface CollectionRenderProps { @@ -40,12 +40,12 @@ export class CollectionBaseView extends React.Component { get collectionViewType(): CollectionViewType | undefined { let Document = this.props.Document; let viewField = Cast(Document.viewType, "number"); - if (viewField === CollectionViewType.Freeform) { - return CollectionViewType.Tree; - } - if (viewField === CollectionViewType.RealFreeform) { - return CollectionViewType.Freeform; - } + // if (viewField === CollectionViewType.Freeform) { + // return CollectionViewType.Tree; + // } + // if (viewField === CollectionViewType.RealFreeform) { + // return CollectionViewType.Freeform; + // } if (viewField !== undefined) { return viewField; } else { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 264c89d67..956a5668a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -211,7 +211,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { let [x, y] = this.getTransform().transformPoint(e.clientX, e.clientY); let localTransform = this.getLocalTransform().inverse().scaleAbout(deltaScale, x, y); - let safeScale = Math.abs(localTransform.Scale); + let safeScale = Math.max(0.002, localTransform.Scale); this.props.Document.scale = Math.abs(safeScale); this.setPan(-localTransform.TranslateX / safeScale, -localTransform.TranslateY / safeScale); e.stopPropagation(); -- cgit v1.2.3-70-g09d2 From ff3ef22630ad9c32b4ed1b0872bbc8b5753761eb Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 18 May 2019 23:16:36 -0400 Subject: fixed zoomBasis issues with wrapping, text size, and normalizing outlines. --- src/client/views/DocumentDecorations.tsx | 34 ++++++++++------------ .../views/collections/CollectionBaseView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 8 ++--- 3 files changed, 21 insertions(+), 23 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index d440ed898..5ec090f05 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -431,31 +431,29 @@ 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) { + if (rect.width !== 0 && (dX != 0 || dY != 0 || dW != 0 || dH != 0)) { let doc = PositionDocument(element.props.Document); - let width = FieldValue(doc.width, 0); - let nwidth = FieldValue(doc.nativeWidth, 0); - let nheight = FieldValue(doc.nativeHeight, 0); - let height = FieldValue(doc.height, nwidth ? nheight / nwidth * width : 0); - let x = FieldValue(doc.x, 0); - let y = FieldValue(doc.y, 0); + let nwidth = doc.nativeWidth || 0; + let nheight = doc.nativeHeight || 0; + let zoomBasis = NumCast(doc.zoomBasis, 1); + let width = (doc.width || 0) / zoomBasis; + let height = (doc.height || (nheight / nwidth * width)) / zoomBasis; let scale = width / rect.width; let actualdW = Math.max(width + (dW * scale), 20); let actualdH = Math.max(height + (dH * scale), 20); - x += dX * (actualdW - width); - y += dY * (actualdH - height); - doc.x = x; - doc.y = y; - var nativeWidth = FieldValue(doc.nativeWidth, 0); - var nativeHeight = FieldValue(doc.nativeHeight, 0); - if (nativeWidth > 0 && nativeHeight > 0) { + doc.x = (doc.x || 0) + dX * (actualdW - width); + doc.y = (doc.y || 0) + dY * (actualdH - height); + if (nwidth > 0 && nheight > 0) { if (Math.abs(dW) > Math.abs(dH)) { - actualdH = nativeHeight / nativeWidth * actualdW; + doc.zoomBasis = zoomBasis * width / actualdW; } - else actualdW = nativeWidth / nativeHeight * actualdH; + else { + doc.zoomBasis = zoomBasis * height / actualdH; + } + } else { + doc.width = zoomBasis * actualdW; + doc.height = zoomBasis * actualdH; } - doc.width = actualdW; - doc.height = actualdH; } }); } diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 2da8c4e40..76270f2e8 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -114,7 +114,7 @@ export class CollectionBaseView extends React.Component { } // set the ZoomBasis only if hasn't already been set -- bcz: maybe set/resetting the ZoomBasis should be a parameter to addDocument? if (!alreadyAdded && (this.collectionViewType === CollectionViewType.Freeform || this.collectionViewType === CollectionViewType.Invalid)) { - let zoom = NumCast(this.props.Document.scale, 1); + let zoom = NumCast(this.props.Document.scale, 1) / this.props.ScreenToLocalTransform().Scale;// ; Doc.SetOnPrototype(doc, "zoomBasis", zoom); } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 33521528f..b4b811da4 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -140,14 +140,14 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY); if (!this.isAnnotationOverlay) { let minx = docs.length ? NumCast(docs[0].x) : 0; - let maxx = docs.length ? NumCast(docs[0].width) + minx : minx; + let maxx = docs.length ? NumCast(docs[0].width) / NumCast(docs[0].zoomBasis) + minx : minx; let miny = docs.length ? NumCast(docs[0].y) : 0; - let maxy = docs.length ? NumCast(docs[0].height) + miny : miny; + let maxy = docs.length ? NumCast(docs[0].height) / NumCast(docs[0].zoomBasis) + miny : miny; let ranges = docs.filter(doc => doc).reduce((range, doc) => { let x = NumCast(doc.x); - let xe = x + NumCast(doc.width); + let xe = x + NumCast(doc.width) / NumCast(doc.zoomBasis); let y = NumCast(doc.y); - let ye = y + NumCast(doc.height); + let ye = y + NumCast(doc.height) / NumCast(doc.zoomBasis); return [[range[0][0] > x ? x : range[0][0], range[0][1] < xe ? xe : range[0][1]], [range[1][0] > y ? y : range[1][0], range[1][1] < ye ? ye : range[1][1]]]; }, [[minx, maxx], [miny, maxy]]); -- cgit v1.2.3-70-g09d2 From 10d7773dccdc3cada5e7e34926de69b9f3631414 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sun, 19 May 2019 02:43:08 -0400 Subject: Added safe mode --- src/client/views/MainView.tsx | 7 +++++++ src/client/views/collections/CollectionBaseView.tsx | 20 ++++++++++++-------- src/client/views/collections/CollectionView.tsx | 4 +++- 3 files changed, 22 insertions(+), 9 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index c3f3a63de..bdd3e9650 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -31,6 +31,7 @@ import { DocServer } from '../DocServer'; import { listSpec } from '../../new_fields/Schema'; import { Id } from '../../new_fields/RefField'; import { HistoryUtil } from '../util/History'; +import { CollectionBaseView } from './collections/CollectionBaseView'; @observer @@ -60,6 +61,12 @@ export class MainView extends React.Component { if (window.location.search.includes("readonly")) { DocServer.makeReadOnly(); } + if (window.location.search.includes("safe")) { + if (!window.location.search.includes("nro")) { + DocServer.makeReadOnly(); + } + CollectionBaseView.SetSafeMode(true); + } if (window.location.pathname !== RouteStore.home) { let pathname = window.location.pathname.substr(1).split("/"); if (pathname.length > 1) { diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 76270f2e8..9d52ce6ff 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -1,4 +1,4 @@ -import { action, computed } from 'mobx'; +import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { ContextMenu } from '../ContextMenu'; @@ -16,7 +16,6 @@ export enum CollectionViewType { Schema, Docking, Tree, - // RealFreeform } export interface CollectionRenderProps { @@ -37,15 +36,20 @@ export interface CollectionViewProps extends FieldViewProps { @observer export class CollectionBaseView extends React.Component { + @observable private static _safeMode = false; + static InSafeMode() { return this._safeMode; } + static SetSafeMode(safeMode: boolean) { this._safeMode = safeMode; } get collectionViewType(): CollectionViewType | undefined { let Document = this.props.Document; let viewField = Cast(Document.viewType, "number"); - // if (viewField === CollectionViewType.Freeform) { - // return CollectionViewType.Tree; - // } - // if (viewField === CollectionViewType.RealFreeform) { - // return CollectionViewType.Freeform; - // } + if (CollectionBaseView._safeMode) { + if (viewField === CollectionViewType.Freeform) { + return CollectionViewType.Tree; + } + if (viewField === CollectionViewType.Invalid) { + return CollectionViewType.Freeform; + } + } if (viewField !== undefined) { return viewField; } else { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 33427a991..b9ffc11a2 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -41,7 +41,9 @@ export class CollectionView extends React.Component { onContextMenu = (e: React.MouseEvent): void => { if (!this.isAnnotationOverlay && !e.isPropagationStopped() && this.props.Document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 ContextMenu.Instance.addItem({ description: "Freeform", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Freeform), icon: "project-diagram" }); - ContextMenu.Instance.addItem({ description: "Freeform2", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.RealFreeform), icon: "project-diagram" }); + if (CollectionBaseView.InSafeMode()) { + ContextMenu.Instance.addItem({ description: "Test Freeform", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Invalid), icon: "project-diagram" }); + } ContextMenu.Instance.addItem({ description: "Schema", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Schema), icon: "project-diagram" }); ContextMenu.Instance.addItem({ description: "Treeview", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Tree), icon: "tree" }); } -- cgit v1.2.3-70-g09d2 From 12796ace87581ffeac9d67fa5d7ebff8cecd1a52 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 19 May 2019 11:33:42 -0400 Subject: added opaque background for non-annotation collections. fixed marquee view when there's zoomBasis, fixed double-click opening to stopPropagation. got rid of RIGHT_BTN_DRAG stuff. --- .../views/collections/CollectionBaseView.tsx | 4 ++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 11 +++-------- .../collections/collectionFreeForm/MarqueeView.tsx | 23 ++++++++-------------- .../views/nodes/CollectionFreeFormDocumentView.tsx | 3 ++- src/client/views/nodes/DocumentView.tsx | 5 +---- 5 files changed, 16 insertions(+), 30 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 76270f2e8..54e76fd5e 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -89,7 +89,7 @@ export class CollectionBaseView extends React.Component { } return false; } - @computed get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey === "annotations"; } + @computed get isAnnotationOverlay() { return this.props.fieldKey === "annotations"; } @action.bound addDocument(doc: Doc, allowDuplicates: boolean = false): boolean { @@ -114,7 +114,7 @@ export class CollectionBaseView extends React.Component { } // set the ZoomBasis only if hasn't already been set -- bcz: maybe set/resetting the ZoomBasis should be a parameter to addDocument? if (!alreadyAdded && (this.collectionViewType === CollectionViewType.Freeform || this.collectionViewType === CollectionViewType.Invalid)) { - let zoom = NumCast(this.props.Document.scale, 1) / this.props.ScreenToLocalTransform().Scale;// ; + let zoom = NumCast(this.props.Document.scale, 1); Doc.SetOnPrototype(doc, "zoomBasis", zoom); } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index b4b811da4..9cb8443f4 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -37,7 +37,6 @@ const PanZoomDocument = makeInterface(panZoomSchema, positionSchema, pageSchema) @observer export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { - public static RIGHT_BTN_DRAG = false; private _selectOnLoaded: string = ""; // id of document that should be selected once it's loaded (used for click-to-type) private _lastX: number = 0; private _lastY: number = 0; @@ -46,8 +45,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { @computed get nativeWidth() { return this.Document.nativeWidth || 0; } @computed get nativeHeight() { return this.Document.nativeHeight || 0; } + public get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey === "annotations"; } private get borderWidth() { return this.isAnnotationOverlay ? 0 : COLLECTION_BORDER_WIDTH; } - private get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey === "annotations"; } private panX = () => this.Document.panX || 0; private panY = () => this.Document.panY || 0; private zoomScaling = () => this.Document.scale || 1; @@ -66,7 +65,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { return true; } private selectDocuments = (docs: Doc[]) => { - SelectionManager.DeselectAll; + SelectionManager.DeselectAll(); docs.map(doc => DocumentManager.Instance.getDocumentView(doc)).filter(dv => dv).map(dv => SelectionManager.SelectDoc(dv!, true)); } @@ -112,11 +111,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { @action onPointerDown = (e: React.PointerEvent): void => { - if ((CollectionFreeFormView.RIGHT_BTN_DRAG && - (((e.button === 2 && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) || - (e.button === 0 && e.altKey)) && this.props.active())) || - (!CollectionFreeFormView.RIGHT_BTN_DRAG && - ((e.button === 0 && !e.shiftKey && !e.altKey && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) && this.props.active()))) { + if (e.button === 0 && !e.shiftKey && !e.altKey && (!this.isAnnotationOverlay || this.zoomScaling() !== 1) && this.props.active()) { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); document.addEventListener("pointermove", this.onPointerMove); diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index d102c8af2..4587c2227 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -132,17 +132,18 @@ export class MarqueeView extends React.Component this._downY = this._lastY = e.pageY; this._commandExecuted = false; PreviewCursor.Visible = false; - if ((CollectionFreeFormView.RIGHT_BTN_DRAG && e.button === 0 && !e.altKey && !e.metaKey && this.props.container.props.active()) || - (!CollectionFreeFormView.RIGHT_BTN_DRAG && (e.button === 2 || (e.button === 0 && e.altKey)) && this.props.container.props.active())) { + if (e.button === 2 || (e.button === 0 && e.altKey)) { + if (!this.props.container.props.active()) this.props.selectDocuments([this.props.container.props.Document]); document.addEventListener("pointermove", this.onPointerMove, true); document.addEventListener("pointerup", this.onPointerUp, true); document.addEventListener("keydown", this.marqueeCommand, true); - // bcz: do we need this? it kills the context menu on the main collection + if (e.altKey) { + e.stopPropagation(); + e.preventDefault(); + } + // bcz: do we need this? it kills the context menu on the main collection if !altKey // e.stopPropagation(); } - if (e.altKey) { - e.preventDefault(); - } } @action @@ -248,6 +249,7 @@ export class MarqueeView extends React.Component panX: 0, panY: 0, borderRounding: e.key === "e" ? -1 : undefined, + backgroundColor: this.props.container.isAnnotationOverlay ? undefined : "white", scale: zoomBasis, width: bounds.width * zoomBasis, height: bounds.height * zoomBasis, @@ -275,15 +277,6 @@ export class MarqueeView extends React.Component //this.props.addDocument(newCollection, false); summary.proto!.summarizedDocs = new List(selected); summary.proto!.maximizeLocation = "inTab"; // or "inPlace", or "onRight" - //summary.proto!.isButton = true; - //let scrpt = this.props.getTransform().inverse().transformPoint(bounds.left, bounds.top); - // selected.map(summarizedDoc => { - // let maxx = NumCast(summarizedDoc.x, undefined); - // let maxy = NumCast(summarizedDoc.y, undefined); - // let maxw = NumCast(summarizedDoc.width, undefined); - // let maxh = NumCast(summarizedDoc.height, undefined); - // summarizedDoc.isIconAnimating = new List([scrpt[0], scrpt[1], maxx, maxy, maxw, maxh, Date.now(), 0]); - // }); this.props.addLiveTextDocument(summary); }); } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 7cb4c1dfe..8851e4b93 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -180,8 +180,9 @@ export class CollectionFreeFormDocumentView extends DocComponent { document.removeEventListener("pointerup", this.onPointerUp); - if (Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2) { + if (!(e as any).propagationIsStopped && Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2) { this.props.addDocTab(this.props.Document, "inTab"); + (e as any).propagationIsStopped = true; } e.stopPropagation(); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 760e31b49..bb5daaf4e 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -187,9 +187,6 @@ export class DocumentView extends DocComponent(Docu onPointerDown = (e: React.PointerEvent): void => { this._downX = e.clientX; this._downY = e.clientY; - if (CollectionFreeFormView.RIGHT_BTN_DRAG && (e.button === 2 || (e.button === 0 && e.altKey)) && !this.isSelected()) { - return; - } this._hitExpander = DocListCast(this.props.Document.subBulletDocs).length > 0; if (e.shiftKey && e.buttons === 1) { CollectionDockingView.Instance.StartOtherDrag([Doc.MakeAlias(this.props.Document)], e); @@ -207,7 +204,7 @@ export class DocumentView extends DocComponent(Docu if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); - if (!e.altKey && !this.topMost && (!CollectionFreeFormView.RIGHT_BTN_DRAG && e.buttons === 1) || (CollectionFreeFormView.RIGHT_BTN_DRAG && e.buttons === 2)) { + if (!e.altKey && !this.topMost && e.buttons === 1) { this.startDragging(this._downX, this._downY, e.ctrlKey || e.altKey ? "alias" : undefined, this._hitExpander); } } -- cgit v1.2.3-70-g09d2 From af2346983eae1145167b70faf96a9aec0ca82427 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Mon, 20 May 2019 00:09:47 -0400 Subject: Fixed a bunch of demo bugs Moved Field Symbols to separate file Editing is mostly working in debug viewer --- deploy/debug/viewer.html | 1 + src/client/DocServer.ts | 3 +- src/client/northstar/dash-fields/HistogramField.ts | 7 +- src/client/northstar/dash-nodes/HistogramBox.tsx | 2 +- src/client/util/DocumentManager.ts | 2 +- src/client/util/SearchUtil.ts | 2 +- src/client/util/TooltipTextMenu.tsx | 2 +- src/client/util/type_decls.d | 128 +++++++-------------- src/client/views/EditableView.tsx | 10 +- src/client/views/MainView.tsx | 2 +- src/client/views/PresentationView.tsx | 2 +- src/client/views/SearchBox.tsx | 2 +- .../views/collections/CollectionBaseView.tsx | 2 +- .../views/collections/CollectionDockingView.tsx | 14 ++- src/client/views/collections/CollectionPDFView.tsx | 2 +- .../views/collections/CollectionSchemaView.tsx | 2 +- .../views/collections/CollectionTreeView.tsx | 2 +- .../views/collections/CollectionVideoView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 2 +- .../views/collections/ParentDocumentSelector.tsx | 2 +- .../CollectionFreeFormLinksView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 3 - src/client/views/nodes/DocumentView.tsx | 4 +- src/client/views/nodes/KeyValueBox.tsx | 4 +- src/client/views/nodes/KeyValuePair.tsx | 4 +- src/client/views/nodes/LinkMenu.tsx | 2 +- src/debug/Viewer.tsx | 53 +++++++-- src/new_fields/CursorField.ts | 7 +- src/new_fields/DateField.ts | 7 +- src/new_fields/Doc.ts | 43 ++++--- src/new_fields/FieldSymbols.ts | 10 ++ src/new_fields/HtmlField.ts | 7 +- src/new_fields/IconField.ts | 7 +- src/new_fields/InkField.ts | 7 +- src/new_fields/List.ts | 16 ++- src/new_fields/ObjectField.ts | 7 +- src/new_fields/Proxy.ts | 9 +- src/new_fields/RefField.ts | 5 +- src/new_fields/RichTextField.ts | 7 +- src/new_fields/URLField.ts | 9 +- src/new_fields/util.ts | 7 +- 42 files changed, 240 insertions(+), 173 deletions(-) create mode 100644 src/new_fields/FieldSymbols.ts (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/deploy/debug/viewer.html b/deploy/debug/viewer.html index 3785a6602..8c265ccb8 100644 --- a/deploy/debug/viewer.html +++ b/deploy/debug/viewer.html @@ -3,6 +3,7 @@ Document Debugger + diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index f1b50d5a0..cbcf751ee 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -3,7 +3,8 @@ import { MessageStore } from "./../server/Message"; import { Opt } from '../new_fields/Doc'; import { Utils, emptyFunction } from '../Utils'; import { SerializationHelper } from './util/SerializationHelper'; -import { RefField, HandleUpdate, Id } from '../new_fields/RefField'; +import { RefField } from '../new_fields/RefField'; +import { Id, HandleUpdate } from '../new_fields/FieldSymbols'; export namespace DocServer { const _cache: { [id: string]: RefField | Promise> } = {}; diff --git a/src/client/northstar/dash-fields/HistogramField.ts b/src/client/northstar/dash-fields/HistogramField.ts index 1ee2189b9..31040a474 100644 --- a/src/client/northstar/dash-fields/HistogramField.ts +++ b/src/client/northstar/dash-fields/HistogramField.ts @@ -3,10 +3,11 @@ import { custom, serializable } from "serializr"; import { ColumnAttributeModel } from "../../../client/northstar/core/attribute/AttributeModel"; import { AttributeTransformationModel } from "../../../client/northstar/core/attribute/AttributeTransformationModel"; import { HistogramOperation } from "../../../client/northstar/operations/HistogramOperation"; -import { ObjectField, Copy } from "../../../new_fields/ObjectField"; +import { ObjectField } from "../../../new_fields/ObjectField"; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; import { OmitKeys } from "../../../Utils"; import { Deserializable } from "../../util/SerializationHelper"; +import { Copy, ToScriptString } from "../../../new_fields/FieldSymbols"; function serialize(field: HistogramField) { let obj = OmitKeys(field, ['Links', 'BrushLinks', 'Result', 'BrushColors', 'FilterModels', 'FilterOperand']).omit; @@ -55,4 +56,8 @@ export class HistogramField extends ObjectField { let z = this.HistoOp.Copy; return new HistogramField(HistogramOperation.Duplicate(this.HistoOp)); } + + [ToScriptString]() { + return "invalid"; + } } \ No newline at end of file diff --git a/src/client/northstar/dash-nodes/HistogramBox.tsx b/src/client/northstar/dash-nodes/HistogramBox.tsx index eb1ad69b7..a9646ed31 100644 --- a/src/client/northstar/dash-nodes/HistogramBox.tsx +++ b/src/client/northstar/dash-nodes/HistogramBox.tsx @@ -19,7 +19,7 @@ import { HistogramLabelPrimitives } from "./HistogramLabelPrimitives"; import { StyleConstants } from "../utils/StyleContants"; import { Cast } from "../../../new_fields/Types"; import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc"; -import { Id } from "../../../new_fields/RefField"; +import { Id } from "../../../new_fields/FieldSymbols"; @observer diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index be448098a..a5e768dcf 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -5,10 +5,10 @@ import { FieldValue, Cast, NumCast, BoolCast } from '../../new_fields/Types'; import { listSpec } from '../../new_fields/Schema'; import { undoBatch } from './UndoManager'; import { CollectionDockingView } from '../views/collections/CollectionDockingView'; -import { Id } from '../../new_fields/RefField'; import { CollectionView } from '../views/collections/CollectionView'; import { CollectionPDFView } from '../views/collections/CollectionPDFView'; import { CollectionVideoView } from '../views/collections/CollectionVideoView'; +import { Id } from '../../new_fields/FieldSymbols'; export class DocumentManager { diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts index 4ccff0d1b..e8eb70837 100644 --- a/src/client/util/SearchUtil.ts +++ b/src/client/util/SearchUtil.ts @@ -1,7 +1,7 @@ import * as rp from 'request-promise'; import { DocServer } from '../DocServer'; import { Doc } from '../../new_fields/Doc'; -import { Id } from '../../new_fields/RefField'; +import { Id } from '../../new_fields/FieldSymbols'; export namespace SearchUtil { export function Search(query: string, returnDocs: true): Promise; diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 4d40d09b2..a1f80120f 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -22,12 +22,12 @@ import { throwStatement } from "babel-types"; import { View } from "@react-pdf/renderer"; import { DragManager } from "./DragManager"; import { Doc, Opt, Field } from "../../new_fields/Doc"; -import { Id } from "../../new_fields/RefField"; import { Utils } from "../northstar/utils/Utils"; import { DocServer } from "../DocServer"; import { CollectionFreeFormDocumentView } from "../views/nodes/CollectionFreeFormDocumentView"; import { CollectionDockingView } from "../views/collections/CollectionDockingView"; import { DocumentManager } from "./DocumentManager"; +import { Id } from "../../new_fields/FieldSymbols"; const SVG = "http://www.w3.org/2000/svg"; diff --git a/src/client/util/type_decls.d b/src/client/util/type_decls.d index 47c3481b2..51114d0e2 100644 --- a/src/client/util/type_decls.d +++ b/src/client/util/type_decls.d @@ -119,104 +119,54 @@ interface URL { username: string; toJSON(): string; } +interface PromiseLike { + then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): PromiseLike; +} +interface Promise { + then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): Promise; + catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): Promise; +} -declare type FieldId = string; +declare const Update: unique symbol; +declare const Self: unique symbol; +declare const SelfProxy: unique symbol; +declare const HandleUpdate: unique symbol; +declare const Id: unique symbol; +declare const OnUpdate: unique symbol; +declare const Parent: unique symbol; +declare const Copy: unique symbol; +declare const ToScriptString: unique symbol; -declare abstract class Field { - Id: FieldId; - abstract ToScriptString(): string; - abstract TrySetValue(value: any): boolean; - abstract GetValue(): any; - abstract Copy(): Field; -} +declare abstract class RefField { + readonly [Id]: FieldId; + + constructor(id?: FieldId); + protected [HandleUpdate]?(diff: any): void; -declare abstract class BasicField extends Field { - constructor(data: T); - Data: T; - TrySetValue(value: any): boolean; - GetValue(): any; + abstract [ToScriptString](): string; } -declare class TextField extends BasicField{ - constructor(); - constructor(data: string); - ToScriptString(): string; - Copy(): Field; -} -declare class ImageField extends BasicField{ - constructor(); - constructor(data: URL); - ToScriptString(): string; - Copy(): Field; -} -declare class HtmlField extends BasicField{ - constructor(); - constructor(data: string); - ToScriptString(): string; - Copy(): Field; -} -declare class NumberField extends BasicField{ - constructor(); - constructor(data: number); - ToScriptString(): string; - Copy(): Field; -} -declare class WebField extends BasicField{ - constructor(); - constructor(data: URL); - ToScriptString(): string; - Copy(): Field; -} -declare class ListField extends BasicField{ - constructor(); - constructor(data: T[]); - ToScriptString(): string; - Copy(): Field; -} -declare class Key extends Field { - constructor(name:string); - Name: string; - TrySetValue(value: any): boolean; - GetValue(): any; - Copy(): Field; - ToScriptString(): string; -} -declare type FIELD_WAITING = null; -declare type Opt = T | undefined; -declare type FieldValue = Opt | FIELD_WAITING; -// @ts-ignore -declare class Document extends Field { - TrySetValue(value: any): boolean; - GetValue(): any; - Copy(): Field; - ToScriptString(): string; +declare abstract class ObjectField { + protected [OnUpdate](diff?: any): void; + private [Parent]?: RefField | ObjectField; + abstract [Copy](): ObjectField; - Width(): number; - Height(): number; - Scale(): number; - Title: string; + abstract [ToScriptString](): string; +} +declare type FieldId = string; - Get(key: Key): FieldValue; - GetAsync(key: Key, callback: (field: Field) => void): boolean; - GetOrCreateAsync(key: Key, ctor: { new(): T }, callback: (field: T) => void): void; - GetT(key: Key, ctor: { new(): T }): FieldValue; - GetOrCreate(key: Key, ctor: { new(): T }): T; - GetData(key: Key, ctor: { new(): U }, defaultVal: T): T; - GetHtml(key: Key, defaultVal: string): string; - GetNumber(key: Key, defaultVal: number): number; - GetText(key: Key, defaultVal: string): string; - GetList(key: Key, defaultVal: T[]): T[]; - Set(key: Key, field: Field | undefined): void; - SetData(key: Key, value: T, ctor: { new(): U }): void; - SetText(key: Key, value: string): void; - SetNumber(key: Key, value: number): void; - GetPrototype(): FieldValue; - GetAllPrototypes(): Document[]; - MakeDelegate(): Document; +declare type Field = number | string | boolean | ObjectField | RefField; + +declare type Opt = T | undefined; +declare class Doc extends RefField { + [key: string]: Field | undefined; + [ToScriptString](): string; } -declare const KeyStore: { - [name: string]: Key; +declare class ListImpl extends ObjectField { + [index: number]: T | (T extends RefField ? Promise : never); + [ToScriptString](): string; + [Copy](): ObjectField; } // @ts-ignore diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 78143ccda..c946d68e1 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -22,7 +22,7 @@ export interface EditableProps { * The contents to render when not editing */ contents: any; - height: number; + height?: number; display?: string; oneLine?: boolean; } @@ -53,6 +53,12 @@ export class EditableView extends React.Component { } } + @action + onClick = (e: React.MouseEvent) => { + this.editing = true; + e.stopPropagation(); + } + render() { if (this.editing) { return this.editing = false)} @@ -60,7 +66,7 @@ export class EditableView extends React.Component { } else { return (
this.editing = true)} > + onClick={this.onClick} > {this.props.contents}
); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 400562f12..9edbba997 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -29,7 +29,7 @@ import { FieldResult, Field, Doc, Opt } from '../../new_fields/Doc'; import { Cast, FieldValue, StrCast } from '../../new_fields/Types'; import { DocServer } from '../DocServer'; import { listSpec } from '../../new_fields/Schema'; -import { Id } from '../../new_fields/RefField'; +import { Id } from '../../new_fields/FieldSymbols'; import { HistoryUtil } from '../util/History'; import { CollectionBaseView } from './collections/CollectionBaseView'; diff --git a/src/client/views/PresentationView.tsx b/src/client/views/PresentationView.tsx index 9c37e9000..ce679aa0a 100644 --- a/src/client/views/PresentationView.tsx +++ b/src/client/views/PresentationView.tsx @@ -7,7 +7,7 @@ import { Utils } from "../../Utils"; import { Doc, DocListCast, DocListCastAsync } from "../../new_fields/Doc"; import { listSpec } from "../../new_fields/Schema"; import { Cast, NumCast, FieldValue, PromiseValue, StrCast } from "../../new_fields/Types"; -import { Id } from "../../new_fields/RefField"; +import { Id } from "../../new_fields/FieldSymbols"; import { List } from "../../new_fields/List"; import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils"; diff --git a/src/client/views/SearchBox.tsx b/src/client/views/SearchBox.tsx index 6e64e1af1..8efd8d266 100644 --- a/src/client/views/SearchBox.tsx +++ b/src/client/views/SearchBox.tsx @@ -16,7 +16,7 @@ import { isString } from 'util'; import { constant } from 'async'; import { DocServer } from '../DocServer'; import { Doc } from '../../new_fields/Doc'; -import { Id } from '../../new_fields/RefField'; +import { Id } from '../../new_fields/FieldSymbols'; import { DocumentManager } from '../util/DocumentManager'; import { SetupDrag } from '../util/DragManager'; import { Docs } from '../documents/Documents'; diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 84ffbac36..5686ccfef 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -7,8 +7,8 @@ import { Cast, FieldValue, PromiseValue, NumCast } from '../../../new_fields/Typ import { Doc, FieldResult, Opt, DocListCast } from '../../../new_fields/Doc'; import { listSpec } from '../../../new_fields/Schema'; import { List } from '../../../new_fields/List'; -import { Id } from '../../../new_fields/RefField'; import { SelectionManager } from '../../util/SelectionManager'; +import { Id } from '../../../new_fields/FieldSymbols'; export enum CollectionViewType { Invalid, diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 483209f86..e904358a9 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -6,7 +6,7 @@ import * as ReactDOM from 'react-dom'; import Measure from "react-measure"; import * as GoldenLayout from "../../../client/goldenLayout"; import { Doc, Field, Opt, DocListCast } from "../../../new_fields/Doc"; -import { FieldId, Id } from "../../../new_fields/RefField"; +import { FieldId } from "../../../new_fields/RefField"; import { listSpec } from "../../../new_fields/Schema"; import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; import { emptyFunction, returnTrue, Utils } from "../../../Utils"; @@ -21,6 +21,7 @@ import React = require("react"); import { ParentDocSelector } from './ParentDocumentSelector'; import { DocumentManager } from '../../util/DocumentManager'; import { CollectionViewType } from './CollectionBaseView'; +import { Id } from '../../../new_fields/FieldSymbols'; @observer export class CollectionDockingView extends React.Component { @@ -75,7 +76,7 @@ export class CollectionDockingView extends React.Component { let retVal = false; if (this._goldenLayout.root.contentItems[0].isRow) { retVal = Array.from(this._goldenLayout.root.contentItems[0].contentItems).some((child: any) => { @@ -118,7 +119,7 @@ export class CollectionDockingView extends React.Component { let docs = Cast(this.props.Document.data, listSpec(Doc)); if (docs) { docs.push(document); @@ -155,7 +156,7 @@ export class CollectionDockingView extends React.Component { let docs = Cast(this.props.Document.data, listSpec(Doc)); if (docs) { docs.push(document); @@ -412,10 +413,11 @@ export class DockedFrameRenderer extends React.Component { @observable private _panelWidth = 0; @observable private _panelHeight = 0; @observable private _document: Opt; - _stack: any; + get _stack(): any { + return (this.props as any).glContainer.parent.parent; + } constructor(props: any) { super(props); - this._stack = (this.props as any).glContainer.parent.parent; DocServer.GetRefField(this.props.documentId).then(action((f: Opt) => this._document = f as Doc)); } diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx index a6614da21..5e51437a4 100644 --- a/src/client/views/collections/CollectionPDFView.tsx +++ b/src/client/views/collections/CollectionPDFView.tsx @@ -8,7 +8,7 @@ import { FieldView, FieldViewProps } from "../nodes/FieldView"; import { CollectionRenderProps, CollectionBaseView, CollectionViewType } from "./CollectionBaseView"; import { emptyFunction } from "../../../Utils"; import { NumCast } from "../../../new_fields/Types"; -import { Id } from "../../../new_fields/RefField"; +import { Id } from "../../../new_fields/FieldSymbols"; @observer diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index f15da41ff..b25b48339 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -23,7 +23,7 @@ import { Opt, Field, Doc, DocListCastAsync, DocListCast } from "../../../new_fie import { Cast, FieldValue, NumCast, StrCast } from "../../../new_fields/Types"; import { listSpec } from "../../../new_fields/Schema"; import { List } from "../../../new_fields/List"; -import { Id } from "../../../new_fields/RefField"; +import { Id } from "../../../new_fields/FieldSymbols"; import { Gateway } from "../../northstar/manager/Gateway"; import { Docs } from "../../documents/Documents"; import { ContextMenu } from "../ContextMenu"; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 72fa69cb1..8ad495762 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -11,7 +11,7 @@ import React = require("react"); import { Document, listSpec } from '../../../new_fields/Schema'; import { Cast, StrCast, BoolCast, FieldValue } from '../../../new_fields/Types'; import { Doc, DocListCast } from '../../../new_fields/Doc'; -import { Id } from '../../../new_fields/RefField'; +import { Id } from '../../../new_fields/FieldSymbols'; import { ContextMenu } from '../ContextMenu'; import { undoBatch } from '../../util/UndoManager'; import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils'; diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx index 9ab959f3c..27f23a1a8 100644 --- a/src/client/views/collections/CollectionVideoView.tsx +++ b/src/client/views/collections/CollectionVideoView.tsx @@ -7,7 +7,7 @@ import "./CollectionVideoView.scss"; import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormView"; import { FieldView, FieldViewProps } from "../nodes/FieldView"; import { emptyFunction } from "../../../Utils"; -import { Id } from "../../../new_fields/RefField"; +import { Id } from "../../../new_fields/FieldSymbols"; import { VideoBox } from "../nodes/VideoBox"; import { NumCast } from "../../../new_fields/Types"; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 59c763be8..bfdef8e8c 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -2,7 +2,7 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { faProjectDiagram, faSquare, faTh, faTree, faSignature, faThList } from '@fortawesome/free-solid-svg-icons'; import { observer } from "mobx-react"; import * as React from 'react'; -import { Id } from '../../../new_fields/RefField'; +import { Id } from '../../../new_fields/FieldSymbols'; import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils'; import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from "../ContextMenu"; diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx index 52f7914f3..4d07c31a7 100644 --- a/src/client/views/collections/ParentDocumentSelector.tsx +++ b/src/client/views/collections/ParentDocumentSelector.tsx @@ -3,7 +3,7 @@ import './ParentDocumentSelector.scss'; import { Doc } from "../../../new_fields/Doc"; import { observer } from "mobx-react"; import { observable, action, runInAction } from "mobx"; -import { Id } from "../../../new_fields/RefField"; +import { Id } from "../../../new_fields/FieldSymbols"; import { SearchUtil } from "../../util/SearchUtil"; import { CollectionDockingView } from "./CollectionDockingView"; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx index d5ce4e1e7..e1ff715d1 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx @@ -11,7 +11,7 @@ import { Doc, DocListCastAsync, DocListCast } from "../../../../new_fields/Doc"; import { Cast, FieldValue, NumCast, StrCast } from "../../../../new_fields/Types"; import { listSpec } from "../../../../new_fields/Schema"; import { List } from "../../../../new_fields/List"; -import { Id } from "../../../../new_fields/RefField"; +import { Id } from "../../../../new_fields/FieldSymbols"; @observer export class CollectionFreeFormLinksView extends React.Component { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9cb8443f4..ee6f4821f 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -22,9 +22,9 @@ import { createSchema, makeInterface, listSpec } from "../../../../new_fields/Sc import { Doc, WidthSym, HeightSym } from "../../../../new_fields/Doc"; import { FieldValue, Cast, NumCast, BoolCast } from "../../../../new_fields/Types"; import { pageSchema } from "../../nodes/ImageBox"; -import { Id } from "../../../../new_fields/RefField"; import { InkField, StrokeData } from "../../../../new_fields/InkField"; import { HistoryUtil } from "../../../util/History"; +import { Id } from "../../../../new_fields/FieldSymbols"; export const panZoomSchema = createSchema({ panX: "number", diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 4587c2227..2029b91e5 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -17,9 +17,6 @@ import { InkField, StrokeData } from "../../../../new_fields/InkField"; import { List } from "../../../../new_fields/List"; import { ImageField } from "../../../../new_fields/URLField"; import { Template, Templates } from "../../Templates"; -import { Gateway } from "../../../northstar/manager/Gateway"; -import { DocServer } from "../../../DocServer"; -import { Id } from "../../../../new_fields/RefField"; interface MarqueeViewProps { getContainerTransform: () => Transform; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 5f218fd1f..87c88f57c 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -4,8 +4,7 @@ import { action, computed, IReactionDisposer, reaction } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../new_fields/Doc"; import { List } from "../../../new_fields/List"; -import { Copy, ObjectField } from "../../../new_fields/ObjectField"; -import { Id } from "../../../new_fields/RefField"; +import { ObjectField } from "../../../new_fields/ObjectField"; import { createSchema, makeInterface } from "../../../new_fields/Schema"; import { BoolCast, Cast, FieldValue, StrCast } from "../../../new_fields/Types"; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; @@ -29,6 +28,7 @@ import { Template } from "./../Templates"; import { DocumentContentsView } from "./DocumentContentsView"; import "./DocumentView.scss"; import React = require("react"); +import { Id, Copy } from '../../../new_fields/FieldSymbols'; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? library.add(faTrash); diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 86437a6c1..8cb576786 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -8,7 +8,7 @@ import "./KeyValueBox.scss"; import { KeyValuePair } from "./KeyValuePair"; import React = require("react"); import { NumCast, Cast, FieldValue } from "../../../new_fields/Types"; -import { Doc, IsField } from "../../../new_fields/Doc"; +import { Doc, Field } from "../../../new_fields/Doc"; @observer export class KeyValueBox extends React.Component { @@ -41,7 +41,7 @@ export class KeyValueBox extends React.Component { let res = script.run(); if (!res.success) return; const field = res.result; - if (IsField(field)) { + if (Field.IsField(field)) { realDoc[this._keyInput] = field; } this._keyInput = ""; diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index 4f7919f50..7a88985c0 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -9,7 +9,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import "./KeyValueBox.scss"; import "./KeyValuePair.scss"; import React = require("react"); -import { Doc, Opt, IsField } from '../../../new_fields/Doc'; +import { Doc, Opt, Field } from '../../../new_fields/Doc'; import { FieldValue } from '../../../new_fields/Types'; // Represents one row in a key value plane @@ -75,7 +75,7 @@ export class KeyValuePair extends React.Component { let res = script.run(); if (!res.success) return false; const field = res.result; - if (IsField(field)) { + if (Field.IsField(field)) { props.Document[props.fieldKey] = field; return true; } diff --git a/src/client/views/nodes/LinkMenu.tsx b/src/client/views/nodes/LinkMenu.tsx index 4cf798249..3f09d6214 100644 --- a/src/client/views/nodes/LinkMenu.tsx +++ b/src/client/views/nodes/LinkMenu.tsx @@ -7,7 +7,7 @@ import './LinkMenu.scss'; import React = require("react"); import { Doc, DocListCast } from "../../../new_fields/Doc"; import { Cast, FieldValue, StrCast } from "../../../new_fields/Types"; -import { Id } from "../../../new_fields/RefField"; +import { Id } from "../../../new_fields/FieldSymbols"; interface Props { docView: DocumentView; diff --git a/src/debug/Viewer.tsx b/src/debug/Viewer.tsx index 720e1640a..4314e2132 100644 --- a/src/debug/Viewer.tsx +++ b/src/debug/Viewer.tsx @@ -3,11 +3,27 @@ import "normalize.css"; import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { observer } from 'mobx-react'; -import { Doc, Field, FieldResult } from '../new_fields/Doc'; +import { Doc, Field, FieldResult, Opt } from '../new_fields/Doc'; import { DocServer } from '../client/DocServer'; -import { Id } from '../new_fields/RefField'; +import { Id } from '../new_fields/FieldSymbols'; import { List } from '../new_fields/List'; import { URLField } from '../new_fields/URLField'; +import { EditableView } from '../client/views/EditableView'; +import { CompileScript } from '../client/util/Scripting'; + +function applyToDoc(doc: { [index: string]: FieldResult }, key: string, scriptString: string): boolean; +function applyToDoc(doc: { [index: number]: FieldResult }, key: number, scriptString: string): boolean; +function applyToDoc(doc: any, key: string | number, scriptString: string): boolean { + let script = CompileScript(scriptString, { addReturn: true, params: { this: doc instanceof Doc ? Doc.name : List.name } }); + if (!script.compiled) { + return false; + } + const res = script.run({ this: doc }); + if (!res.success) return false; + if (!Field.IsField(res.result)) return false; + doc[key] = res.result; + return true; +} configure({ enforceActions: "observed" @@ -18,12 +34,18 @@ class ListViewer extends React.Component<{ field: List }>{ @observable expanded = false; + @action + onClick = (e: React.MouseEvent) => { + this.expanded = !this.expanded; + e.stopPropagation(); + } + render() { let content; if (this.expanded) { content = (
- {this.props.field.map((field, index) => )} + {this.props.field.map((field, index) => applyToDoc(this.props.field, index, value)} />)}
); } else { @@ -31,7 +53,7 @@ class ListViewer extends React.Component<{ field: List }>{ } return (
- + {content}
); @@ -42,6 +64,13 @@ class ListViewer extends React.Component<{ field: List }>{ class DocumentViewer extends React.Component<{ field: Doc }> { @observable expanded = false; + + @action + onClick = (e: React.MouseEvent) => { + this.expanded = !this.expanded; + e.stopPropagation(); + } + render() { let content; if (this.expanded) { @@ -50,7 +79,7 @@ class DocumentViewer extends React.Component<{ field: Doc }> { return (
({key}): - + applyToDoc(this.props.field, key, value)}>
); }); @@ -67,7 +96,7 @@ class DocumentViewer extends React.Component<{ field: Doc }> { } return (
- + {content}
); @@ -75,7 +104,7 @@ class DocumentViewer extends React.Component<{ field: Doc }> { } @observer -class DebugViewer extends React.Component<{ field: FieldResult }> { +class DebugViewer extends React.Component<{ field: FieldResult, setValue(value: string): boolean }> { render() { let content; @@ -90,10 +119,14 @@ class DebugViewer extends React.Component<{ field: FieldResult }> { content =

{field}

; } else if (field instanceof URLField) { content =

{field.url.href}

; + } else if (field instanceof Promise) { + return

Field loading

; } else { - content =

Unrecognized field type

; + return

Unrecognized field type

; } - return content; + + return Field.toScriptString(field)} SetValue={this.props.setValue} + contents={content}>; } } @@ -129,7 +162,7 @@ class Viewer extends React.Component { onChange={this.inputOnChange} onKeyDown={this.onKeyPress} />
- {this.fields.map((field, index) => )} + {this.fields.map((field, index) => false}>)}
); diff --git a/src/new_fields/CursorField.ts b/src/new_fields/CursorField.ts index fc144222c..1be1ec3e0 100644 --- a/src/new_fields/CursorField.ts +++ b/src/new_fields/CursorField.ts @@ -1,7 +1,8 @@ -import { ObjectField, Copy, OnUpdate } from "./ObjectField"; +import { ObjectField } from "./ObjectField"; import { observable } from "mobx"; import { Deserializable } from "../client/util/SerializationHelper"; import { serializable, createSimpleSchema, object } from "serializr"; +import { OnUpdate, ToScriptString, Copy } from "./FieldSymbols"; export type CursorPosition = { x: number, @@ -52,4 +53,8 @@ export default class CursorField extends ObjectField { [Copy]() { return new CursorField(this.data); } + + [ToScriptString]() { + return "invalid"; + } } \ No newline at end of file diff --git a/src/new_fields/DateField.ts b/src/new_fields/DateField.ts index c0a79f267..fc8abb9d9 100644 --- a/src/new_fields/DateField.ts +++ b/src/new_fields/DateField.ts @@ -1,6 +1,7 @@ import { Deserializable } from "../client/util/SerializationHelper"; import { serializable, date } from "serializr"; -import { ObjectField, Copy } from "./ObjectField"; +import { ObjectField } from "./ObjectField"; +import { Copy, ToScriptString } from "./FieldSymbols"; @Deserializable("date") export class DateField extends ObjectField { @@ -15,4 +16,8 @@ export class DateField extends ObjectField { [Copy]() { return new DateField(this.date); } + + [ToScriptString]() { + return `new DateField(new Date(${this.date.toISOString()}))`; + } } diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 02dd34cb4..f4514c33e 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -5,27 +5,33 @@ import { DocServer } from "../client/DocServer"; import { setter, getter, getField, updateFunction, deleteProperty } from "./util"; import { Cast, ToConstructor, PromiseValue, FieldValue, NumCast } from "./Types"; import { listSpec } from "./Schema"; -import { ObjectField, Parent, OnUpdate } from "./ObjectField"; -import { RefField, FieldId, Id, HandleUpdate } from "./RefField"; - -export function IsField(field: any): field is Field { - return (typeof field === "string") - || (typeof field === "number") - || (typeof field === "boolean") - || (field instanceof ObjectField) - || (field instanceof RefField); +import { ObjectField } from "./ObjectField"; +import { RefField, FieldId } from "./RefField"; +import { ToScriptString, SelfProxy, Parent, OnUpdate, Self, HandleUpdate, Update, Id } from "./FieldSymbols"; + +export namespace Field { + export function toScriptString(field: Field): string { + if (typeof field === "string") { + return `"${field}"`; + } else if (typeof field === "number" || typeof field === "boolean") { + return String(field); + } else { + return field[ToScriptString](); + } + } + export function IsField(field: any): field is Field { + return (typeof field === "string") + || (typeof field === "number") + || (typeof field === "boolean") + || (field instanceof ObjectField) + || (field instanceof RefField); + } } export type Field = number | string | boolean | ObjectField | RefField; export type Opt = T | undefined; export type FieldWaiting = T extends undefined ? never : Promise; export type FieldResult = Opt | FieldWaiting>; -export const Update = Symbol("Update"); -export const Self = Symbol("Self"); -export const SelfProxy = Symbol("SelfProxy"); -export const WidthSym = Symbol("Width"); -export const HeightSym = Symbol("Height"); - /** * Cast any field to either a List of Docs or undefined if the given field isn't a List of Docs. * If a default value is given, that will be returned instead of undefined. @@ -43,6 +49,9 @@ export function DocListCast(field: FieldResult): Doc[] { return Cast(field, listSpec(Doc), []).filter(d => d instanceof Doc) as Doc[]; } +export const WidthSym = Symbol("Width"); +export const HeightSym = Symbol("Height"); + @Deserializable("doc").withFields(["id"]) export class Doc extends RefField { constructor(id?: FieldId, forceSave?: boolean) { @@ -102,6 +111,10 @@ export class Doc extends RefField { public [WidthSym] = () => NumCast(this[SelfProxy].width); // bcz: is this the right way to access width/height? it didn't work with : this.width public [HeightSym] = () => NumCast(this[SelfProxy].height); + [ToScriptString]() { + return "invalid"; + } + public [HandleUpdate](diff: any) { console.log(diff); const set = diff.$set; diff --git a/src/new_fields/FieldSymbols.ts b/src/new_fields/FieldSymbols.ts new file mode 100644 index 000000000..a436dcf2b --- /dev/null +++ b/src/new_fields/FieldSymbols.ts @@ -0,0 +1,10 @@ + +export const Update = Symbol("Update"); +export const Self = Symbol("Self"); +export const SelfProxy = Symbol("SelfProxy"); +export const HandleUpdate = Symbol("HandleUpdate"); +export const Id = Symbol("Id"); +export const OnUpdate = Symbol("OnUpdate"); +export const Parent = Symbol("Parent"); +export const Copy = Symbol("Copy"); +export const ToScriptString = Symbol("Copy"); \ No newline at end of file diff --git a/src/new_fields/HtmlField.ts b/src/new_fields/HtmlField.ts index d998746bb..f952acff9 100644 --- a/src/new_fields/HtmlField.ts +++ b/src/new_fields/HtmlField.ts @@ -1,6 +1,7 @@ import { Deserializable } from "../client/util/SerializationHelper"; import { serializable, primitive } from "serializr"; -import { ObjectField, Copy } from "./ObjectField"; +import { ObjectField } from "./ObjectField"; +import { Copy, ToScriptString } from "./FieldSymbols"; @Deserializable("html") export class HtmlField extends ObjectField { @@ -15,4 +16,8 @@ export class HtmlField extends ObjectField { [Copy]() { return new HtmlField(this.html); } + + [ToScriptString]() { + return "invalid"; + } } diff --git a/src/new_fields/IconField.ts b/src/new_fields/IconField.ts index 1a928389d..62b2cd254 100644 --- a/src/new_fields/IconField.ts +++ b/src/new_fields/IconField.ts @@ -1,6 +1,7 @@ import { Deserializable } from "../client/util/SerializationHelper"; import { serializable, primitive } from "serializr"; -import { ObjectField, Copy } from "./ObjectField"; +import { ObjectField } from "./ObjectField"; +import { Copy, ToScriptString } from "./FieldSymbols"; @Deserializable("icon") export class IconField extends ObjectField { @@ -15,4 +16,8 @@ export class IconField extends ObjectField { [Copy]() { return new IconField(this.icon); } + + [ToScriptString]() { + return "invalid"; + } } diff --git a/src/new_fields/InkField.ts b/src/new_fields/InkField.ts index 2d75f8a19..4e3b7abe0 100644 --- a/src/new_fields/InkField.ts +++ b/src/new_fields/InkField.ts @@ -1,6 +1,7 @@ import { Deserializable } from "../client/util/SerializationHelper"; import { serializable, custom, createSimpleSchema, list, object, map } from "serializr"; -import { ObjectField, Copy } from "./ObjectField"; +import { ObjectField } from "./ObjectField"; +import { Copy, ToScriptString } from "./FieldSymbols"; import { deepCopy } from "../Utils"; export enum InkTool { @@ -40,4 +41,8 @@ export class InkField extends ObjectField { [Copy]() { return new InkField(deepCopy(this.inkData)); } + + [ToScriptString]() { + return "invalid"; + } } diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts index 70e36f911..f1e4c4721 100644 --- a/src/new_fields/List.ts +++ b/src/new_fields/List.ts @@ -1,11 +1,12 @@ import { Deserializable, autoObject } from "../client/util/SerializationHelper"; -import { Field, Update, Self, FieldResult, SelfProxy } from "./Doc"; +import { Field } from "./Doc"; import { setter, getter, deleteProperty, updateFunction } from "./util"; import { serializable, alias, list } from "serializr"; import { observable, action } from "mobx"; -import { ObjectField, OnUpdate, Copy, Parent } from "./ObjectField"; +import { ObjectField } from "./ObjectField"; import { RefField } from "./RefField"; import { ProxyField } from "./Proxy"; +import { Self, Update, Parent, OnUpdate, SelfProxy, ToScriptString, Copy } from "./FieldSymbols"; const listHandlers: any = { /// Mutator methods @@ -225,7 +226,7 @@ type StoredType = T extends RefField ? ProxyField : T; @Deserializable("list") class ListImpl extends ObjectField { - constructor(fields: T[] = []) { + constructor(fields?: T[]) { super(); const list = new Proxy(this, { set: setter, @@ -244,7 +245,9 @@ class ListImpl extends ObjectField { defineProperty: () => { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); }, }); this[SelfProxy] = list; - (list as any).push(...fields); + if (fields) { + (list as any).push(...fields); + } return list; } @@ -284,6 +287,11 @@ class ListImpl extends ObjectField { private [Self] = this; private [SelfProxy]: any; + + [ToScriptString]() { + return "invalid"; + // return `new List([${(this as any).map((field => Field.toScriptString(field))}])`; + } } export type List = ListImpl & (T | (T extends RefField ? Promise : never))[]; export const List: { new (fields?: T[]): List } = ListImpl as any; \ No newline at end of file diff --git a/src/new_fields/ObjectField.ts b/src/new_fields/ObjectField.ts index 51768c6db..5f4a6f8fb 100644 --- a/src/new_fields/ObjectField.ts +++ b/src/new_fields/ObjectField.ts @@ -1,14 +1,13 @@ import { Doc } from "./Doc"; import { RefField } from "./RefField"; - -export const OnUpdate = Symbol("OnUpdate"); -export const Parent = Symbol("Parent"); -export const Copy = Symbol("Copy"); +import { OnUpdate, Parent, Copy, ToScriptString } from "./FieldSymbols"; export abstract class ObjectField { protected [OnUpdate](diff?: any) { } private [Parent]?: RefField | ObjectField; abstract [Copy](): ObjectField; + + abstract [ToScriptString](): string; } export namespace ObjectField { diff --git a/src/new_fields/Proxy.ts b/src/new_fields/Proxy.ts index fd99ae1c0..130ec066e 100644 --- a/src/new_fields/Proxy.ts +++ b/src/new_fields/Proxy.ts @@ -3,8 +3,9 @@ import { FieldWaiting } from "./Doc"; import { primitive, serializable } from "serializr"; import { observable, action } from "mobx"; import { DocServer } from "../client/DocServer"; -import { RefField, Id } from "./RefField"; -import { ObjectField, Copy } from "./ObjectField"; +import { RefField } from "./RefField"; +import { ObjectField } from "./ObjectField"; +import { Id, Copy, ToScriptString } from "./FieldSymbols"; @Deserializable("proxy") export class ProxyField extends ObjectField { @@ -26,6 +27,10 @@ export class ProxyField extends ObjectField { return new ProxyField(this.fieldId); } + [ToScriptString]() { + return "invalid"; + } + @serializable(primitive()) readonly fieldId: string = ""; diff --git a/src/new_fields/RefField.ts b/src/new_fields/RefField.ts index 202c65f21..75ce4287f 100644 --- a/src/new_fields/RefField.ts +++ b/src/new_fields/RefField.ts @@ -1,9 +1,8 @@ import { serializable, primitive, alias } from "serializr"; import { Utils } from "../Utils"; +import { Id, HandleUpdate, ToScriptString } from "./FieldSymbols"; export type FieldId = string; -export const HandleUpdate = Symbol("HandleUpdate"); -export const Id = Symbol("Id"); export abstract class RefField { @serializable(alias("id", primitive())) private __id: FieldId; @@ -15,4 +14,6 @@ export abstract class RefField { } protected [HandleUpdate]?(diff: any): void; + + abstract [ToScriptString](): string; } diff --git a/src/new_fields/RichTextField.ts b/src/new_fields/RichTextField.ts index eb30e76de..89d077a47 100644 --- a/src/new_fields/RichTextField.ts +++ b/src/new_fields/RichTextField.ts @@ -1,6 +1,7 @@ -import { ObjectField, Copy } from "./ObjectField"; +import { ObjectField } from "./ObjectField"; import { serializable } from "serializr"; import { Deserializable } from "../client/util/SerializationHelper"; +import { Copy, ToScriptString } from "./FieldSymbols"; @Deserializable("RichTextField") export class RichTextField extends ObjectField { @@ -15,4 +16,8 @@ export class RichTextField extends ObjectField { [Copy]() { return new RichTextField(this.Data); } + + [ToScriptString]() { + return "invalid"; + } } \ No newline at end of file diff --git a/src/new_fields/URLField.ts b/src/new_fields/URLField.ts index d00a95a16..a6f8f1cc5 100644 --- a/src/new_fields/URLField.ts +++ b/src/new_fields/URLField.ts @@ -1,6 +1,7 @@ import { Deserializable } from "../client/util/SerializationHelper"; import { serializable, custom } from "serializr"; -import { ObjectField, Copy } from "./ObjectField"; +import { ObjectField } from "./ObjectField"; +import { ToScriptString, Copy } from "./FieldSymbols"; function url() { return custom( @@ -13,7 +14,7 @@ function url() { ); } -export class URLField extends ObjectField { +export abstract class URLField extends ObjectField { @serializable(url()) readonly url: URL; @@ -22,6 +23,10 @@ export class URLField extends ObjectField { this.url = url; } + [ToScriptString]() { + return `new ${this.constructor.name}(new URL(${this.url.href}))`; + } + [Copy](): this { return new (this.constructor as any)(this.url); } diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts index d94994a07..65a37a0d1 100644 --- a/src/new_fields/util.ts +++ b/src/new_fields/util.ts @@ -1,11 +1,12 @@ import { UndoManager } from "../client/util/UndoManager"; -import { Update, Doc, Field } from "./Doc"; +import { Doc, Field } from "./Doc"; import { SerializationHelper } from "../client/util/SerializationHelper"; import { ProxyField } from "./Proxy"; import { FieldValue } from "./Types"; -import { RefField, Id } from "./RefField"; -import { ObjectField, Parent, OnUpdate } from "./ObjectField"; +import { RefField } from "./RefField"; +import { ObjectField } from "./ObjectField"; import { action } from "mobx"; +import { Parent, OnUpdate, Update, Id } from "./FieldSymbols"; export const setter = action(function (target: any, prop: string | symbol | number, value: any, receiver: any): boolean { if (SerializationHelper.IsSerializing()) { -- cgit v1.2.3-70-g09d2 From ab001ffd9749814c3f0b0f30e9f86f65e2f8ac0c Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Tue, 21 May 2019 20:49:49 -0400 Subject: "Rebased" Stanley's image upload changes --- src/client/documents/Documents.ts | 3 ++ src/client/views/Main.scss | 15 ++++++ src/client/views/MainView.tsx | 33 ++++++++++--- .../views/collections/CollectionBaseView.tsx | 1 + .../views/collections/CollectionStackingView.scss | 44 ++++++++++++++++++ .../views/collections/CollectionStackingView.tsx | 54 ++++++++++++++++++++++ src/client/views/collections/CollectionView.tsx | 3 ++ src/mobile/ImageUpload.scss | 21 ++++++++- src/mobile/ImageUpload.tsx | 1 + .../authentication/models/current_user_utils.ts | 2 +- 10 files changed, 168 insertions(+), 9 deletions(-) create mode 100644 src/client/views/collections/CollectionStackingView.scss create mode 100644 src/client/views/collections/CollectionStackingView.tsx (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 3d65826a9..b17544229 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -292,6 +292,9 @@ export namespace Docs { export function TreeDocument(documents: Array, options: DocumentOptions) { return CreateInstance(collProto, new List(documents), { schemaColumns: new List(["title"]), ...options, viewType: CollectionViewType.Tree }); } + export function StackingDocument(documents: Array, options: DocumentOptions) { + return CreateInstance(collProto, new List(documents), { schemaColumns: new List(["title"]), ...options, viewType: CollectionViewType.Stacking }); + } export function DockDocument(documents: Array, config: string, options: DocumentOptions, id?: string) { return CreateInstance(collProto, new List(documents), { ...options, viewType: CollectionViewType.Docking, dockingConfig: config }, id); } diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss index d63b0147b..302c49c10 100644 --- a/src/client/views/Main.scss +++ b/src/client/views/Main.scss @@ -97,6 +97,21 @@ button:hover { right: 0px; } +.main-notifs-badge { + position: absolute; + top: -10px; + right: -10px; + color: white; + background: #f44b42; + font-weight: 300; + border-radius: 100%; + width: 25px; + height: 25px; + text-align: center; + padding-top: 4px; + font-size: 12px; +} + //toolbar stuff #toolbar { position: absolute; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index af224747d..1d491d11f 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -1,5 +1,5 @@ import { IconName, library } from '@fortawesome/fontawesome-svg-core'; -import { faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faTree, faUndoAlt } from '@fortawesome/free-solid-svg-icons'; +import { faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faTree, faUndoAlt, faBell } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, configure, observable, runInAction, trace } from 'mobx'; import { observer } from 'mobx-react'; @@ -25,7 +25,7 @@ import { DocumentView } from './nodes/DocumentView'; import { PreviewCursor } from './PreviewCursor'; import { SearchBox } from './SearchBox'; import { SelectionManager } from '../util/SelectionManager'; -import { FieldResult, Field, Doc, Opt } from '../../new_fields/Doc'; +import { FieldResult, Field, Doc, Opt, DocListCast } from '../../new_fields/Doc'; import { Cast, FieldValue, StrCast } from '../../new_fields/Types'; import { DocServer } from '../DocServer'; import { listSpec } from '../../new_fields/Schema'; @@ -137,12 +137,14 @@ export class MainView extends React.Component { // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container) setTimeout(() => { this.openWorkspace(mainDoc); - let pendingDocument = Docs.SchemaDocument(["title"], [], { title: "New Mobile Uploads" }); - mainDoc.optionalRightCollection = pendingDocument; + // let pendingDocument = Docs.StackingDocument([], { title: "New Mobile Uploads" }); + // mainDoc.optionalRightCollection = pendingDocument; }, 0); } } + @observable _notifsCol: Opt; + @action openWorkspace = async (doc: Doc, fromHistory = false) => { CurrentUserUtils.MainDocId = doc[Id]; @@ -153,12 +155,19 @@ export class MainView extends React.Component { setTimeout(async () => { if (col) { const l = Cast(col.data, listSpec(Doc)); - if (l && l.length > 0) { - CollectionDockingView.Instance.AddRightSplit(col); + if (l) { + runInAction(() => this._notifsCol = col); } } }, 100); } + + openNotifsCol = () => { + if (this._notifsCol) { + CollectionDockingView.Instance.AddRightSplit(this._notifsCol); + } + } + @action onResize = (r: any) => { this.pwidth = r.offset.width; @@ -254,11 +263,23 @@ export class MainView extends React.Component { /* @TODO this should really be moved into a moveable toolbar component, but for now let's put it here to meet the deadline */ @computed get miscButtons() { + const length = this._notifsCol ? DocListCast(this._notifsCol.data).length : 0; + const notifsRef = React.createRef(); + const dragNotifs = action(() => this._notifsCol!); let logoutRef = React.createRef(); return [ ,
+
+ +
0 ? { "display": "initial" } : { "display": "none" }}> + {length} +
+
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 5686ccfef..2bccde241 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -16,6 +16,7 @@ export enum CollectionViewType { Schema, Docking, Tree, + Stacking } export interface CollectionRenderProps { diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss new file mode 100644 index 000000000..803e680e5 --- /dev/null +++ b/src/client/views/collections/CollectionStackingView.scss @@ -0,0 +1,44 @@ +@import "../globalCssVariables"; + +.collectionStackingView { + top: 0; + left: 0; + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + position: absolute; + overflow-y: scroll; + min-width: 250px; + border-width: 0; + box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw; + border-color: $light-color-secondary; + border-style: solid; + border-radius: 0 0 $border-radius $border-radius; + box-sizing: border-box; + + .collectionStackingView-docView-container { + width: 45%; + margin: 5% 2.5%; + padding-left: 2.5%; + height: auto; + } + + .collectionStackingView-flexCont { + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: center; + } + + .collectionStackingView-description { + font-size: 100%; + margin-bottom: 1vw; + padding: 10px; + height: 2vw; + width: 100%; + font-family: $sans-serif; + background: $dark-color; + color: $light-color; + } +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx new file mode 100644 index 000000000..a1cb73123 --- /dev/null +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -0,0 +1,54 @@ +import React = require("react"); +import { observer } from "mobx-react"; +import { CollectionSubView } from "./CollectionSubView"; +import Measure from "react-measure"; +import { Doc, WidthSym, HeightSym } from "../../../new_fields/Doc"; +import { DocumentView } from "../nodes/DocumentView"; +import { Transform } from "../../util/Transform"; +import { emptyFunction, returnOne } from "../../../Utils"; +import "./CollectionStackingView.scss"; +import { runInAction, action, observable, computed } from "mobx"; +import { StrCast } from "../../../new_fields/Types"; + +@observer +export class CollectionStackingView extends CollectionSubView(doc => doc) { + getPreviewTransform = (): Transform => this.props.ScreenToLocalTransform(); + + @action + moveDocument = (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean): boolean => { + this.props.removeDocument(doc); + addDocument(doc); + return true; + } + + render() { + const docs = this.childDocs; + return ( +
e.stopPropagation()}> +
{StrCast(this.props.Document.documentText, StrCast(this.props.Document.title, "stacking collection"))}
+
+ {docs.map(d => { + return (
+ +
); + })} +
+
+ ); + } +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index bfdef8e8c..39c8af4ab 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -12,6 +12,7 @@ import { CollectionDockingView } from "./CollectionDockingView"; import { CollectionSchemaView } from "./CollectionSchemaView"; import { CollectionTreeView } from "./CollectionTreeView"; import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; +import { CollectionStackingView } from './CollectionStackingView'; export const COLLECTION_BORDER_WIDTH = 2; library.add(faTh); @@ -31,6 +32,7 @@ export class CollectionView extends React.Component { case CollectionViewType.Schema: return (); case CollectionViewType.Docking: return (); case CollectionViewType.Tree: return (); + case CollectionViewType.Stacking: return (); case CollectionViewType.Freeform: default: return (); @@ -48,6 +50,7 @@ export class CollectionView extends React.Component { } ContextMenu.Instance.addItem({ description: "Schema", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Schema), icon: "th-list" }); ContextMenu.Instance.addItem({ description: "Treeview", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Tree), icon: "tree" }); + ContextMenu.Instance.addItem({ description: "Stacking", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Stacking), icon: "th-list" }); } } diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss index d0b7d4e41..65305dd04 100644 --- a/src/mobile/ImageUpload.scss +++ b/src/mobile/ImageUpload.scss @@ -1,7 +1,13 @@ +@import "../client/views/globalCssVariables.scss"; + .imgupload_cont { - height: 100vh; + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; width: 100vw; - align-content: center; + height: 100vh; + .button_file { text-align: center; height: 50%; @@ -10,4 +16,15 @@ color: grey; font-size: 3em; } + + .upload_label { + width: 80vw; + height: 40vh; + background: $dark-color; + font-size: 10vw; + font-family: $sans-serif; + text-align: center; + padding-top: 20vh; + color: white; + } } \ No newline at end of file diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx index 690937339..84bbfeb14 100644 --- a/src/mobile/ImageUpload.tsx +++ b/src/mobile/ImageUpload.tsx @@ -71,6 +71,7 @@ const onFileLoad = async (file: React.ChangeEvent) => { ReactDOM.render((
{/* */} +
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index b947f5e01..e85aa2c74 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -37,7 +37,7 @@ export class CurrentUserUtils { doc.title = this.email; doc.data = new List(); doc.excludeFromLibrary = true; - doc.optionalRightCollection = Docs.SchemaDocument(["title"], [], { title: "Pending documents" }); + doc.optionalRightCollection = Docs.StackingDocument([], { title: "New mobile uploads" }); // doc.library = Docs.TreeDocument([doc], { title: `Library: ${CurrentUserUtils.email}` }); // (doc.library as Doc).excludeFromLibrary = true; return doc; -- cgit v1.2.3-70-g09d2 From 37e16bb59a38c000ba80312a0661e1f54c93f3c6 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 30 May 2019 10:51:00 -0400 Subject: cleaned up event handling for documentviews. fixed context menu closing. --- src/client/documents/Documents.ts | 2 +- src/client/views/ContextMenu.tsx | 7 +- src/client/views/ContextMenuItem.tsx | 34 +++-- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/MainView.tsx | 1 - .../views/collections/CollectionBaseView.tsx | 1 + .../views/collections/CollectionDockingView.tsx | 1 - .../views/collections/CollectionSchemaView.tsx | 1 - .../views/collections/CollectionStackingView.tsx | 28 +---- .../views/collections/CollectionTreeView.tsx | 22 ++-- .../CollectionFreeFormLinksView.tsx | 1 - .../collectionFreeForm/CollectionFreeFormView.tsx | 1 - .../views/nodes/CollectionFreeFormDocumentView.tsx | 119 ------------------ src/client/views/nodes/DocumentView.tsx | 140 ++++++++++++++++----- src/client/views/nodes/FieldView.tsx | 1 - 15 files changed, 153 insertions(+), 208 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index fffada459..ab61b915c 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -295,7 +295,7 @@ export namespace Docs { return CreateInstance(webProto, new HtmlField(html), options); } export function KVPDocument(document: Doc, options: DocumentOptions = {}) { - return CreateInstance(kvpProto, document, options); + return CreateInstance(kvpProto, document, { title: document.title + ".kvp", ...options }); } export function FreeformDocument(documents: Array, options: DocumentOptions, makePrototype: boolean = true) { if (!makePrototype) { diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index 542d259d6..da374455e 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -81,6 +81,11 @@ export class ContextMenu extends React.Component { return false; } + @action + closeMenu = () => { + this.clearItems(); + } + render() { let style = this._yRelativeToTop ? { left: this._pageX, top: this._pageY, display: this._display } : { left: this._pageX, bottom: this._pageY, display: this._display }; @@ -95,7 +100,7 @@ export class ContextMenu extends React.Component { {this._items.filter(prop => prop.description.toLowerCase().indexOf(this._searchString.toLowerCase()) !== -1). - map(prop => )} + map(prop => )}
); } diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index b9239dac9..63347e076 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -8,11 +8,13 @@ export interface OriginalMenuProps { description: string; event: (e: React.MouseEvent) => void; icon?: IconProp; //maybe should be optional (icon?) + closeMenu?: () => void; } export interface SubmenuProps { description: string; subitems: ContextMenuProps[]; + closeMenu?: () => void; } export interface ContextMenuItemProps { @@ -32,30 +34,36 @@ export class ContextMenuItem extends React.Component { } } + handleEvent = (e: React.MouseEvent) => { + if ("event" in this.props) { + this.props.event(e); + this.props.closeMenu && this.props.closeMenu(); + } + } + render() { if ("event" in this.props) { return ( -
+
{this.props.icon ? : } -
{this.props.description}
+
+ {this.props.description} +
); } else { - let submenu = null; - if (this.overItem) { - submenu = ( -
- {this._items.map(prop => )} -
- ); - } + let submenu = !this.overItem ? (null) : +
+ {this._items.map(prop => )} +
; return ( -
{ this.overItem = true; })} - onMouseLeave={action(() => this.overItem = false)}> -
{this.props.description}
+
{ this.overItem = true; })} onMouseLeave={action(() => this.overItem = false)}> +
+ {this.props.description} +
{submenu}
); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 319e91337..e06fd6119 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -251,7 +251,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } if (!this._removeIcon) { if (selectedDocs.length === 1) { - this.getIconDoc(selectedDocs[0]).then(icon => selectedDocs[0].props.toggleMinimized()); + this.getIconDoc(selectedDocs[0]).then(icon => selectedDocs[0].toggleMinimized()); } else if (Math.abs(e.pageX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.pageY - this._downY) < Utils.DRAG_THRESHOLD) { let docViews = SelectionManager.ViewsSortedVertically(); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 438607157..74dafadc4 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -184,7 +184,6 @@ export class MainView extends React.Component { let mainCont = this.mainContainer; let content = !mainCont ? (null) : { @action.bound removeDocument(doc: Doc): boolean { + SelectionManager.DeselectAll(); const props = this.props; //TODO This won't create the field if it doesn't already exist const value = Cast(props.Document[props.fieldKey], listSpec(Doc), []); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 180a8be46..b6076b5f7 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -466,7 +466,6 @@ export class DockedFrameRenderer extends React.Component {
doc) { - + _masonryGridRef: HTMLDivElement | null = null; get gridGap() { return 10; } get gridSize() { return 20; } get itemWidth() { return NumCast(this.props.Document.itemWidth, 250); } - constructor(props: SubCollectionViewProps) { - super(props); - } - @action moveDocument = (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean): boolean => { this.props.removeDocument(doc); @@ -31,13 +27,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { } getDocTransform(doc: Doc, dref: HTMLDivElement) { let { scale, translateX, translateY } = Utils.GetScreenTransform(dref); - let outerXf = Utils.GetScreenTransform(this.masonryGridRef!); + let outerXf = Utils.GetScreenTransform(this._masonryGridRef!); let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY); return this.props.ScreenToLocalTransform().translate(offset[0], offset[1]).scale(NumCast(doc.width, 1) / this.itemWidth); } - masonryGridRef: HTMLDivElement | null = null; createRef = (ele: HTMLDivElement | null) => { - this.masonryGridRef = ele; + this._masonryGridRef = ele; this.createDropTarget(ele!); } @computed @@ -77,32 +72,17 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { parentActive={this.props.active} addDocTab={this.props.addDocTab} bringToFront={emptyFunction} - toggleMinimized={emptyFunction} whenActiveChanged={this.props.whenActiveChanged} />
); }) } - onClick = (e: React.MouseEvent) => { - let hitBackground = (e.target as any).className === "collectionStackingView-masonryGrid" || - (e.target as any).className === "collectionStackingView"; - if (this.props.active()) { - if (!hitBackground) - e.stopPropagation(); - } - if (hitBackground) { - if (!this.props.active() && this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.active()) { - e.stopPropagation(); - } - this.props.select(false); - } - } render() { let leftMargin = 20; let topMargin = 20; let itemCols = Math.ceil(this.itemWidth / (this.gridSize + this.gridGap)); let cells = Math.floor((this.props.PanelWidth() - leftMargin) / (itemCols * (this.gridSize + this.gridGap))); return ( -
e.stopPropagation()}> +
e.stopPropagation()}>
void; moveDocument: DragManager.MoveFunction; dropAction: "alias" | "copy" | undefined; + addDocTab: (doc: Doc, where: string) => void; } export enum BulletType { @@ -140,19 +141,12 @@ class TreeView extends React.Component { onWorkspaceContextMenu = (e: React.MouseEvent): void => { if (!e.isPropagationStopped() && this.props.document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 ContextMenu.Instance.addItem({ description: "Open as Workspace", event: undoBatch(() => MainView.Instance.openWorkspace(this.props.document)) }); - ContextMenu.Instance.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.document) }); - ContextMenu.Instance.addItem({ - description: "Open Fields", event: () => CollectionDockingView.Instance.AddRightSplit(Docs.KVPDocument(this.props.document, - { title: this.props.document.title + ".kvp", width: 300, height: 300 })) - }); + ContextMenu.Instance.addItem({ description: "Open Right", event: () => this.props.addDocTab(this.props.document, "onRight") }); + ContextMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.KVPDocument(this.props.document, { width: 300, height: 300 }), "onRight") }); if (DocumentManager.Instance.getDocumentViews(this.props.document).length) { ContextMenu.Instance.addItem({ description: "Focus", event: () => DocumentManager.Instance.getDocumentViews(this.props.document).map(view => view.props.focus(this.props.document)) }); } - ContextMenu.Instance.addItem({ - description: "Delete", event: undoBatch(() => { - this.props.deleteDoc(this.props.document); - }) - }); + ContextMenu.Instance.addItem({ description: "Delete", event: undoBatch(() => this.props.deleteDoc(this.props.document)) }); ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15); e.stopPropagation(); } @@ -180,7 +174,7 @@ class TreeView extends React.Component { {(key === "data") ? (null) : {key}}
- {TreeView.GetChildElements(doc instanceof Doc ? [doc] : docList, key !== "data", (doc: Doc) => this.remove(doc, key), this.move, this.props.dropAction)} + {TreeView.GetChildElements(doc instanceof Doc ? [doc] : docList, key !== "data", (doc: Doc) => this.remove(doc, key), this.move, this.props.dropAction, this.props.addDocTab)}
); } else { @@ -197,9 +191,9 @@ class TreeView extends React.Component {
; } - public static GetChildElements(docs: Doc[], allowMinimized: boolean, remove: ((doc: Doc) => void), move: DragManager.MoveFunction, dropAction: dropActionType) { + public static GetChildElements(docs: Doc[], allowMinimized: boolean, remove: ((doc: Doc) => void), move: DragManager.MoveFunction, dropAction: dropActionType, addDocTab: (doc: Doc, where: string) => void) { return docs.filter(child => !child.excludeFromLibrary && (allowMinimized || !child.isMinimized)).map(child => - ); + ); } } @@ -225,7 +219,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { if (!this.childDocs) { return (null); } - let childElements = TreeView.GetChildElements(this.childDocs, false, this.remove, this.props.moveDocument, dropAction); + let childElements = TreeView.GetChildElements(this.childDocs, false, this.remove, this.props.moveDocument, dropAction, this.props.addDocTab); return (
{ let srcViews = this.documentAnchors(connection.a); let targetViews = this.documentAnchors(connection.b); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index d1c4fb72d..1a1614ac7 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -279,7 +279,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { getDocumentViewProps(document: Doc): DocumentViewProps { return { Document: document, - toggleMinimized: emptyFunction, addDocument: this.props.addDocument, removeDocument: this.props.removeDocument, moveDocument: this.props.moveDocument, diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 5d11e051d..411e8c059 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -30,9 +30,6 @@ const FreeformDocument = makeInterface(schema, positionSchema); @observer export class CollectionFreeFormDocumentView extends DocComponent(FreeformDocument) { private _mainCont = React.createRef(); - private _downX: number = 0; - private _downY: number = 0; - private _doubleTap = false; _bringToFrontDisposer?: IReactionDisposer; @computed get transform() { @@ -62,7 +59,6 @@ export class CollectionFreeFormDocumentView extends DocComponent this.nativeWidth > 0 ? this.width / this.nativeWidth : 1; panelWidth = () => this.props.PanelWidth(); panelHeight = () => this.props.PanelHeight(); - toggleMinimized = async () => this.toggleIcon(await DocListCastAsync(this.props.Document.maximizedDocs)); getTransform = (): Transform => this.props.ScreenToLocalTransform() .translate(-this.X, -this.Y) .scale(1 / this.contentScaling()).scale(1 / this.zoom) @@ -70,7 +66,6 @@ export class CollectionFreeFormDocumentView extends DocComponent => { - SelectionManager.DeselectAll(); - let isMinimized: boolean | undefined; - let minimizedDoc: Doc | undefined = this.props.Document; - if (!maximizedDocs) { - minimizedDoc = await Cast(this.props.Document.minimizedDoc, Doc); - if (minimizedDoc) maximizedDocs = await DocListCastAsync(minimizedDoc.maximizedDocs); - } - if (minimizedDoc && maximizedDocs) { - let minimizedTarget = minimizedDoc; - if (!CollectionFreeFormDocumentView._undoBatch) { - CollectionFreeFormDocumentView._undoBatch = UndoManager.StartBatch("iconAnimating"); - } - maximizedDocs.map(d => Doc.GetProto(d)).map(maximizedDoc => { - let iconAnimating = Cast(maximizedDoc.isIconAnimating, List); - if (!iconAnimating || (Date.now() - iconAnimating[2] > 1000)) { - if (isMinimized === undefined) { - isMinimized = BoolCast(maximizedDoc.isMinimized, false); - } - let minx = NumCast(minimizedTarget.x, undefined) + NumCast(minimizedTarget.width, undefined) / 2; - let miny = NumCast(minimizedTarget.y, undefined) + NumCast(minimizedTarget.height, undefined) / 2; - if (minx !== undefined && miny !== undefined) { - let scrpt = this.props.ScreenToLocalTransform().inverse().transformPoint(minx, miny); - maximizedDoc.willMaximize = isMinimized; - maximizedDoc.isMinimized = false; - maximizedDoc.isIconAnimating = new List([scrpt[0], scrpt[1], Date.now(), isMinimized ? 1 : 0]); - } - } - }); - setTimeout(() => { - CollectionFreeFormDocumentView._undoBatch && CollectionFreeFormDocumentView._undoBatch.end(); - CollectionFreeFormDocumentView._undoBatch = undefined; - }, 500); - } - } - static _undoBatch?: UndoManager.Batch = undefined; - onPointerDown = (e: React.PointerEvent): void => { - this._downX = e.clientX; - this._downY = e.clientY; - this._doubleTap = false; - if (e.button === 0 && e.altKey) { - e.stopPropagation(); // prevents panning from happening on collection if shift is pressed after a document drag has started - } // allow pointer down to go through otherwise so that marquees can be drawn starting over a document - - if (e.button === 0) { - e.preventDefault(); // prevents Firefox from dragging images (we want to do that ourself) - } - } - onClick = async (e: React.MouseEvent) => { - e.stopPropagation(); - let altKey = e.altKey; - let ctrlKey = e.ctrlKey; - if (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && - Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD) { - let isExpander = (e.target as any).id === "isExpander"; - if (BoolCast(this.props.Document.isButton, false) || isExpander) { - SelectionManager.DeselectAll(); - let subBulletDocs = await DocListCastAsync(this.props.Document.subBulletDocs); - let maximizedDocs = await DocListCastAsync(this.props.Document.maximizedDocs); - let summarizedDocs = await DocListCastAsync(this.props.Document.summarizedDocs); - let linkedToDocs = await DocListCastAsync(this.props.Document.linkedToDocs, []); - let linkedFromDocs = await DocListCastAsync(this.props.Document.linkedFromDocs, []); - let expandedDocs: Doc[] = []; - expandedDocs = subBulletDocs ? [...subBulletDocs, ...expandedDocs] : expandedDocs; - expandedDocs = maximizedDocs ? [...maximizedDocs, ...expandedDocs] : expandedDocs; - expandedDocs = summarizedDocs ? [...summarizedDocs, ...expandedDocs] : expandedDocs; - // let expandedDocs = [...(subBulletDocs ? subBulletDocs : []), ...(maximizedDocs ? maximizedDocs : []), ...(summarizedDocs ? summarizedDocs : []),]; - if (expandedDocs.length) { // bcz: need a better way to associate behaviors with click events on widget-documents - let expandedProtoDocs = expandedDocs.map(doc => Doc.GetProto(doc)); - let maxLocation = StrCast(this.props.Document.maximizeLocation, "inPlace"); - let getDispDoc = (target: Doc) => Object.getOwnPropertyNames(target).indexOf("isPrototype") === -1 ? target : Doc.MakeDelegate(target); - if (altKey) { - maxLocation = this.props.Document.maximizeLocation = (maxLocation === "inPlace" || !maxLocation ? "inTab" : "inPlace"); - if (!maxLocation || maxLocation === "inPlace") { - let hadView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedProtoDocs[0], this.props.ContainingCollectionView); - let wasMinimized = !hadView && expandedDocs.reduce((min, d) => !min && !BoolCast(d.IsMinimized, false), false); - expandedDocs.forEach(maxDoc => Doc.GetProto(maxDoc).isMinimized = false); - let hasView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedProtoDocs[0], this.props.ContainingCollectionView); - if (!hasView) { - this.props.addDocument && expandedDocs.forEach(async maxDoc => this.props.addDocument!(getDispDoc(maxDoc), false)); - } - expandedProtoDocs.forEach(maxDoc => maxDoc.isMinimized = wasMinimized); - } - } - if (maxLocation && maxLocation !== "inPlace") { - let dataDocs = DocListCast(CollectionDockingView.Instance.props.Document.data); - if (dataDocs) { - expandedDocs.forEach(maxDoc => - (!CollectionDockingView.Instance.CloseRightSplit(Doc.GetProto(maxDoc)) && - this.props.addDocTab(getDispDoc(maxDoc), maxLocation))); - } - } else { - this.toggleIcon(expandedProtoDocs); - } - } - else if (linkedToDocs.length || linkedFromDocs.length) { - let linkedFwdDocs = [ - linkedToDocs.length ? linkedToDocs[0].linkedTo as Doc : linkedFromDocs.length ? linkedFromDocs[0].linkedFrom as Doc : expandedDocs[0], - linkedFromDocs.length ? linkedFromDocs[0].linkedFrom as Doc : linkedToDocs.length ? linkedToDocs[0].linkedTo as Doc : expandedDocs[0]]; - - let linkedFwdPage = [ - linkedToDocs.length ? NumCast(linkedToDocs[0].linkedToPage, undefined) : linkedFromDocs.length ? NumCast(linkedFromDocs[0].linkedFromPage, undefined) : undefined, - linkedFromDocs.length ? NumCast(linkedFromDocs[0].linkedFromPage, undefined) : linkedToDocs.length ? NumCast(linkedToDocs[0].linkedToPage, undefined) : undefined]; - if (!linkedFwdDocs.some(l => l instanceof Promise)) { - let maxLocation = StrCast(linkedFwdDocs[altKey ? 1 : 0].maximizeLocation, "inTab"); - DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, document => this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey ? 1 : 0]); - } - } - } - } - } borderRounding = () => { let br = NumCast(this.props.Document.borderRounding); @@ -261,8 +144,6 @@ export class CollectionFreeFormDocumentView extends DocComponent boolean; whenActiveChanged: (isActive: boolean) => void; - toggleMinimized: () => void; bringToFront: (doc: Doc) => void; addDocTab: (doc: Doc, where: string) => void; + whenClicked?: () => void; } const schema = createSchema({ @@ -103,6 +103,9 @@ const Document = makeInterface(schema); export class DocumentView extends DocComponent(Document) { private _downX: number = 0; private _downY: number = 0; + private _lastTap: number = 0; + private _doubleTap = false; + private _hitExpander = false; private _mainCont = React.createRef(); private _dropDisposer?: DragManager.DragDropDisposer; @@ -182,23 +185,112 @@ export class DocumentView extends DocComponent(Docu }); } } + toggleMinimized = async () => { + let minimizedDoc = await Cast(this.props.Document.minimizedDoc, Doc); + if (minimizedDoc) { + let scrpt = this.props.ScreenToLocalTransform().inverse().transformPoint( + NumCast(minimizedDoc.x) - NumCast(this.Document.x), NumCast(minimizedDoc.y) - NumCast(this.Document.y)); + this.collapseToPoint(scrpt, await DocListCastAsync(minimizedDoc.maximizedDocs)); + } + } - _doubleTap = false; - onClick = (e: React.MouseEvent): void => { + static _undoBatch?: UndoManager.Batch = undefined; + @action + public collapseToPoint = async (scrpt: number[], expandedDocs: Doc[] | undefined): Promise => { + SelectionManager.DeselectAll(); + if (expandedDocs) { + if (!DocumentView._undoBatch) { + DocumentView._undoBatch = UndoManager.StartBatch("iconAnimating"); + } + let isMinimized: boolean | undefined; + expandedDocs.map(d => Doc.GetProto(d)).map(maximizedDoc => { + let iconAnimating = Cast(maximizedDoc.isIconAnimating, List); + if (!iconAnimating || (Date.now() - iconAnimating[2] > 1000)) { + if (isMinimized === undefined) { + isMinimized = BoolCast(maximizedDoc.isMinimized, false); + } + maximizedDoc.willMaximize = isMinimized; + maximizedDoc.isMinimized = false; + maximizedDoc.isIconAnimating = new List([scrpt[0], scrpt[1], Date.now(), isMinimized ? 1 : 0]); + } + }); + setTimeout(() => { + DocumentView._undoBatch && DocumentView._undoBatch.end(); + DocumentView._undoBatch = undefined; + }, 500); + } + } + onClick = async (e: React.MouseEvent) => { + e.stopPropagation(); + let altKey = e.altKey; + let ctrlKey = e.ctrlKey; if (this._doubleTap && !this.props.isTopMost) { this.props.addDocTab(this.props.Document, "inTab"); SelectionManager.DeselectAll(); this.props.Document.libraryBrush = false; - e.stopPropagation(); } else if (CurrentUserUtils.MainDocId !== this.props.Document[Id] && (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) { SelectionManager.SelectDoc(this, e.ctrlKey); + let isExpander = (e.target as any).id === "isExpander"; + if (BoolCast(this.props.Document.isButton, false) || isExpander) { + SelectionManager.DeselectAll(); + let subBulletDocs = await DocListCastAsync(this.props.Document.subBulletDocs); + let maximizedDocs = await DocListCastAsync(this.props.Document.maximizedDocs); + let summarizedDocs = await DocListCastAsync(this.props.Document.summarizedDocs); + let linkedToDocs = await DocListCastAsync(this.props.Document.linkedToDocs, []); + let linkedFromDocs = await DocListCastAsync(this.props.Document.linkedFromDocs, []); + let expandedDocs: Doc[] = []; + expandedDocs = subBulletDocs ? [...subBulletDocs, ...expandedDocs] : expandedDocs; + expandedDocs = maximizedDocs ? [...maximizedDocs, ...expandedDocs] : expandedDocs; + expandedDocs = summarizedDocs ? [...summarizedDocs, ...expandedDocs] : expandedDocs; + // let expandedDocs = [...(subBulletDocs ? subBulletDocs : []), ...(maximizedDocs ? maximizedDocs : []), ...(summarizedDocs ? summarizedDocs : []),]; + if (expandedDocs.length) { // bcz: need a better way to associate behaviors with click events on widget-documents + let expandedProtoDocs = expandedDocs.map(doc => Doc.GetProto(doc)); + let maxLocation = StrCast(this.props.Document.maximizeLocation, "inPlace"); + let getDispDoc = (target: Doc) => Object.getOwnPropertyNames(target).indexOf("isPrototype") === -1 ? target : Doc.MakeDelegate(target); + if (altKey) { + maxLocation = this.props.Document.maximizeLocation = (maxLocation === "inPlace" || !maxLocation ? "inTab" : "inPlace"); + if (!maxLocation || maxLocation === "inPlace") { + let hadView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedProtoDocs[0], this.props.ContainingCollectionView); + let wasMinimized = !hadView && expandedDocs.reduce((min, d) => !min && !BoolCast(d.IsMinimized, false), false); + expandedDocs.forEach(maxDoc => Doc.GetProto(maxDoc).isMinimized = false); + let hasView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedProtoDocs[0], this.props.ContainingCollectionView); + if (!hasView) { + this.props.addDocument && expandedDocs.forEach(async maxDoc => this.props.addDocument!(getDispDoc(maxDoc), false)); + } + expandedProtoDocs.forEach(maxDoc => maxDoc.isMinimized = wasMinimized); + } + } + if (maxLocation && maxLocation !== "inPlace") { + let dataDocs = DocListCast(CollectionDockingView.Instance.props.Document.data); + if (dataDocs) { + expandedDocs.forEach(maxDoc => + (!CollectionDockingView.Instance.CloseRightSplit(Doc.GetProto(maxDoc)) && + this.props.addDocTab(getDispDoc(maxDoc), maxLocation))); + } + } else { + let scrpt = this.props.ScreenToLocalTransform().inverse().transformPoint(NumCast(this.Document.width) / 2, NumCast(this.Document.height) / 2); + this.collapseToPoint(scrpt, expandedProtoDocs); + } + } + else if (linkedToDocs.length || linkedFromDocs.length) { + let linkedFwdDocs = [ + linkedToDocs.length ? linkedToDocs[0].linkedTo as Doc : linkedFromDocs.length ? linkedFromDocs[0].linkedFrom as Doc : expandedDocs[0], + linkedFromDocs.length ? linkedFromDocs[0].linkedFrom as Doc : linkedToDocs.length ? linkedToDocs[0].linkedTo as Doc : expandedDocs[0]]; + + let linkedFwdPage = [ + linkedToDocs.length ? NumCast(linkedToDocs[0].linkedToPage, undefined) : linkedFromDocs.length ? NumCast(linkedFromDocs[0].linkedFromPage, undefined) : undefined, + linkedFromDocs.length ? NumCast(linkedFromDocs[0].linkedFromPage, undefined) : linkedToDocs.length ? NumCast(linkedToDocs[0].linkedToPage, undefined) : undefined]; + if (!linkedFwdDocs.some(l => l instanceof Promise)) { + let maxLocation = StrCast(linkedFwdDocs[altKey ? 1 : 0].maximizeLocation, "inTab"); + DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, document => this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey ? 1 : 0]); + } + } + } } } - private _lastTap: number = 0; - _hitExpander = false; onPointerDown = (e: React.PointerEvent): void => { this._downX = e.clientX; this._downY = e.clientY; @@ -206,8 +298,8 @@ export class DocumentView extends DocComponent(Docu if (e.shiftKey && e.buttons === 1) { CollectionDockingView.Instance.StartOtherDrag([Doc.MakeAlias(this.props.Document)], e); e.stopPropagation(); - } else if (this.active) { - //e.stopPropagation(); // bcz: doing this will block click events from CollectionFreeFormDocumentView which are needed for iconifying,etc + } else { + if (this.active) e.stopPropagation(); // events stop at the lowest document that is active. document.removeEventListener("pointermove", this.onPointerMove); document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); @@ -215,7 +307,7 @@ export class DocumentView extends DocComponent(Docu } } onPointerMove = (e: PointerEvent): void => { - if (!e.cancelBubble) { + if (!e.cancelBubble && this.active) { if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); @@ -234,32 +326,22 @@ export class DocumentView extends DocComponent(Docu this._lastTap = Date.now(); } - deleteClicked = (): void => { - this.props.removeDocument && this.props.removeDocument(this.props.Document); - } - fieldsClicked = (e: React.MouseEvent): void => { - let kvp = Docs.KVPDocument(this.props.Document, { title: this.props.Document.title + ".kvp", width: 300, height: 300 }); - CollectionDockingView.Instance.AddRightSplit(kvp); - } - makeButton = (e: React.MouseEvent): void => { - let doc = this.props.Document.proto ? this.props.Document.proto : this.props.Document; + deleteClicked = (): void => { this.props.removeDocument && this.props.removeDocument(this.props.Document); } + fieldsClicked = (): void => { this.props.addDocTab(Docs.KVPDocument(this.Document, { width: 300, height: 300 }), "onRight") }; + makeBtnClicked = (): void => { + let doc = Doc.GetProto(this.props.Document); doc.isButton = !BoolCast(doc.isButton, false); if (StrCast(doc.layout).indexOf("Formatted") !== -1) { // only need to freeze the dimensions of text boxes since they don't have a native width and height naturally if (doc.isButton && !doc.nativeWidth) { doc.nativeWidth = this.props.Document[WidthSym](); doc.nativeHeight = this.props.Document[HeightSym](); } else { - doc.nativeWidth = doc.nativeHeight = undefined; } } } - fullScreenClicked = (e: React.MouseEvent): void => { - const doc = Doc.MakeCopy(this.props.Document, false); - if (doc) { - CollectionDockingView.Instance.OpenFullScreen(doc); - } - ContextMenu.Instance.clearItems(); + fullScreenClicked = (): void => { + CollectionDockingView.Instance.OpenFullScreen(Doc.MakeCopy(this.props.Document, false)); SelectionManager.DeselectAll(); } @@ -332,7 +414,7 @@ export class DocumentView extends DocComponent(Docu cm.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document), icon: "caret-square-right" }); cm.addItem({ description: "Fields", event: this.fieldsClicked, icon: "layer-group" }); cm.addItem({ description: "Pin to Pres", event: () => PresentationView.Instance.PinDoc(this.props.Document), icon: "map-pin" }); - cm.addItem({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeButton, icon: "concierge-bell" }); + cm.addItem({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeBtnClicked, icon: "concierge-bell" }); cm.addItem({ description: "Find aliases", event: async () => { const aliases = await SearchUtil.GetAliasesOfDocument(this.props.Document); diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index d3d765eed..7b642b299 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -102,7 +102,6 @@ export class FieldView extends React.Component { layoutKey={"layout"} ContainingCollectionView={this.props.ContainingCollectionView} parentActive={this.props.active} - toggleMinimized={emptyFunction} whenActiveChanged={this.props.whenActiveChanged} bringToFront={emptyFunction} /> ); -- cgit v1.2.3-70-g09d2 From d1b0f462ced168f3a9ac5d007ba1219e98a3b6cf Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 31 May 2019 18:18:05 -0400 Subject: stacking views and more.. --- src/client/views/MainOverlayTextBox.tsx | 11 +++++++-- .../views/collections/CollectionBaseView.tsx | 2 +- .../views/collections/CollectionStackingView.scss | 2 +- .../views/collections/CollectionStackingView.tsx | 28 +++++++++++++++------- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/FormattedTextBox.tsx | 13 ++++------ 6 files changed, 36 insertions(+), 22 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index 6e8e6f8ce..24327b995 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -7,6 +7,8 @@ import { Transform } from '../util/Transform'; import "normalize.css"; import "./MainOverlayTextBox.scss"; import { FormattedTextBox } from './nodes/FormattedTextBox'; +import { CollectionDockingView } from './collections/CollectionDockingView'; +import { Doc } from '../../new_fields/Doc'; interface MainOverlayTextBoxProps { } @@ -82,6 +84,11 @@ export class MainOverlayTextBox extends React.Component document.removeEventListener('pointerup', this.textBoxUp); } + addDocTab = (doc: Doc, location: string) => { + if (true) { // location === "onRight") { need to figure out stack to add "inTab" + CollectionDockingView.Instance.AddRightSplit(doc); + } + } render() { if (FormattedTextBox.InputBoxOverlay && this._textTargetDiv) { let textRect = this._textTargetDiv.getBoundingClientRect(); @@ -91,10 +98,10 @@ export class MainOverlayTextBox extends React.Component style={{ width: `${textRect.width * s}px`, height: `${textRect.height * s}px` }}> + ScreenToLocalTransform={this._textXf} PanelWidth={returnZero} PanelHeight={returnZero} focus={emptyFunction} addDocTab={this.addDocTab} />
; } - else return (null); + else return (null); Z } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index e89b8be0f..734669893 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -120,7 +120,7 @@ export class CollectionBaseView extends React.Component { // set the ZoomBasis only if hasn't already been set -- bcz: maybe set/resetting the ZoomBasis should be a parameter to addDocument? if (!alreadyAdded && (this.collectionViewType === CollectionViewType.Freeform || this.collectionViewType === CollectionViewType.Invalid)) { let zoom = NumCast(this.props.Document.scale, 1); - Doc.SetOnPrototype(doc, "zoomBasis", zoom); + // Doc.GetProto(doc).zoomBasis = zoom; } } return true; diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss index 1bb0b2674..1ab335cc3 100644 --- a/src/client/views/collections/CollectionStackingView.scss +++ b/src/client/views/collections/CollectionStackingView.scss @@ -6,7 +6,7 @@ display: flex; flex-direction: column; width: 100%; - height: 100%; + height: auto; position: absolute; overflow-y: auto; border-width: 0; diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index bf246d4ec..a616b5ac7 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -1,24 +1,36 @@ import React = require("react"); +import { action, computed, IReactionDisposer, reaction } from "mobx"; import { observer } from "mobx-react"; -import { CollectionSubView, CollectionViewProps, SubCollectionViewProps } from "./CollectionSubView"; -import { Doc, WidthSym, HeightSym, DocListCast } from "../../../new_fields/Doc"; -import { DocumentView } from "../nodes/DocumentView"; -import { Transform } from "../../util/Transform"; +import { Doc, HeightSym, WidthSym } from "../../../new_fields/Doc"; +import { Id } from "../../../new_fields/FieldSymbols"; +import { NumCast } from "../../../new_fields/Types"; import { emptyFunction, returnOne, Utils } from "../../../Utils"; +import { DocumentView } from "../nodes/DocumentView"; import "./CollectionStackingView.scss"; -import { action, reaction, trace, computed } from "mobx"; -import { StrCast, NumCast } from "../../../new_fields/Types"; -import { Id } from "../../../new_fields/FieldSymbols"; +import { CollectionSubView } from "./CollectionSubView"; @observer export class CollectionStackingView extends CollectionSubView(doc => doc) { _masonryGridRef: HTMLDivElement | null = null; + _heightDisposer?: IReactionDisposer; get gridGap() { return 10; } get gridSize() { return 20; } get itemWidth() { return NumCast(this.props.Document.itemWidth, 250); } + componentDidMount() { + this._heightDisposer = reaction(() => [this.childDocs.map(d => d[HeightSym]()), this.props.PanelWidth()], + () => { + let hgt = (this.props.PanelWidth() > 500) ? this.props.Document[HeightSym]() : + this.childDocs.filter(d => !d.isMinimized).reduce((height, d) => height + d[HeightSym]() + this.gridGap, this.gridGap + 20 /* top margin */); + this.props.Document.height = hgt; + }, { fireImmediately: true }); + } + componentWillUnmount() { + if (this._heightDisposer) this._heightDisposer(); + } + @action moveDocument = (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean): boolean => { this.props.removeDocument(doc); @@ -37,7 +49,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { } @computed get children() { - return this.childDocs.map(d => { + return this.childDocs.filter(d => !d.isMinimized).map(d => { let colSpan = Math.ceil((this.itemWidth + this.gridGap) / (this.gridSize + this.gridGap)); let rowSpan = Math.ceil((this.itemWidth / d[WidthSym]() * d[HeightSym]() + this.gridGap) / (this.gridSize + this.gridGap)); let dref = React.createRef(); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 69691b6f3..f3a596558 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -328,7 +328,7 @@ export class DocumentView extends DocComponent(Docu } deleteClicked = (): void => { this.props.removeDocument && this.props.removeDocument(this.props.Document); } - fieldsClicked = (): void => { this.props.addDocTab(Docs.KVPDocument(this.Document, { width: 300, height: 300 }), "onRight") }; + 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); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 5d93edaac..3b61c68dd 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -230,20 +230,15 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe this._toolTipTextMenu.tooltip.style.opacity = "0"; } } + let ctrlKey = e.ctrlKey; if (e.button === 0 && ((!this.props.isSelected() && !e.ctrlKey) || (this.props.isSelected() && e.ctrlKey)) && !e.metaKey) { if (e.target && (e.target as any).href) { let href = (e.target as any).href; if (href.indexOf(DocServer.prepend("/doc/")) === 0) { let docid = href.replace(DocServer.prepend("/doc/"), "").split("?")[0]; - DocServer.GetRefField(docid).then(action((f: Opt) => { - if (f instanceof Doc) { - if (DocumentManager.Instance.getDocumentView(f)) { - DocumentManager.Instance.getDocumentView(f)!.props.focus(f); - } else { - this.props.addDocTab && this.props.addDocTab(f, "onRight"); - } - } - })); + DocServer.GetRefField(docid).then(f => { + (f instanceof Doc) && DocumentManager.Instance.jumpToDocument(f, ctrlKey, document => this.props.addDocTab(document, "inTab")) + }); } e.stopPropagation(); e.preventDefault(); -- cgit v1.2.3-70-g09d2 From a37faf30652c6c593923198ad34e54377e670caf Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 5 Jun 2019 08:09:10 -0400 Subject: fixed full screen text bug. cleaned up imports --- src/client/views/DocumentDecorations.tsx | 33 +++++++++++----------- src/client/views/InkingControl.tsx | 1 - src/client/views/PresentationView.tsx | 16 +++++------ src/client/views/SearchItem.tsx | 8 ++---- src/client/views/TemplateMenu.tsx | 11 ++++---- .../views/collections/CollectionBaseView.tsx | 12 ++++---- .../views/collections/CollectionDockingView.tsx | 15 +++++----- .../views/collections/CollectionSchemaView.tsx | 1 - src/client/views/collections/CollectionSubView.tsx | 31 ++++++++++---------- .../views/collections/CollectionTreeView.tsx | 26 ++++++++--------- .../CollectionFreeFormLinkView.tsx | 7 ++--- .../CollectionFreeFormLinksView.tsx | 14 ++++----- .../CollectionFreeFormRemoteCursors.tsx | 12 ++++---- .../collectionFreeForm/CollectionFreeFormView.tsx | 20 ++++++------- .../collections/collectionFreeForm/MarqueeView.tsx | 26 ++++++++--------- src/client/views/nodes/FieldView.tsx | 29 +++++++++---------- src/client/views/nodes/FormattedTextBox.tsx | 6 ++-- src/client/views/nodes/ImageBox.tsx | 24 ++++++++-------- src/client/views/nodes/VideoBox.tsx | 16 +++++------ src/client/views/nodes/WebBox.tsx | 9 +++--- 20 files changed, 147 insertions(+), 170 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index da9b1253e..37895516a 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -1,33 +1,32 @@ -import { action, computed, observable, runInAction, untracked, reaction } from "mobx"; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faLink } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { action, computed, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; +import { Doc } from "../../new_fields/Doc"; +import { List } from "../../new_fields/List"; +import { listSpec } from "../../new_fields/Schema"; +import { Cast, NumCast, StrCast } from "../../new_fields/Types"; import { emptyFunction, Utils } from "../../Utils"; +import { Docs } from "../documents/Documents"; +import { DocumentManager } from "../util/DocumentManager"; import { DragLinksAsDocuments, DragManager } from "../util/DragManager"; import { SelectionManager } from "../util/SelectionManager"; import { undoBatch } from "../util/UndoManager"; +import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss"; +import { CollectionView } from "./collections/CollectionView"; import './DocumentDecorations.scss'; import { DocumentView, PositionDocument } from "./nodes/DocumentView"; +import { FieldView } from "./nodes/FieldView"; +import { FormattedTextBox } from "./nodes/FormattedTextBox"; +import { IconBox } from "./nodes/IconBox"; import { LinkMenu } from "./nodes/LinkMenu"; import { TemplateMenu } from "./TemplateMenu"; -import React = require("react"); import { Template, Templates } from "./Templates"; -import { CompileScript } from "../util/Scripting"; -import { IconBox } from "./nodes/IconBox"; -import { Cast, FieldValue, NumCast, StrCast } from "../../new_fields/Types"; -import { Doc, FieldResult } from "../../new_fields/Doc"; -import { listSpec } from "../../new_fields/Schema"; -import { Docs } from "../documents/Documents"; -import { List } from "../../new_fields/List"; +import React = require("react"); const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; -import { faLink } from '@fortawesome/free-solid-svg-icons'; -import { library } from '@fortawesome/fontawesome-svg-core'; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss"; -import { CollectionView } from "./collections/CollectionView"; -import { DocumentManager } from "../util/DocumentManager"; -import { FormattedTextBox } from "./nodes/FormattedTextBox"; -import { FieldView } from "./nodes/FieldView"; library.add(faLink); diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx index d456f531f..d1a6eb7fd 100644 --- a/src/client/views/InkingControl.tsx +++ b/src/client/views/InkingControl.tsx @@ -1,5 +1,4 @@ import { observable, action, computed } from "mobx"; - import { CirclePicker, ColorResult } from 'react-color'; import React = require("react"); import { observer } from "mobx-react"; diff --git a/src/client/views/PresentationView.tsx b/src/client/views/PresentationView.tsx index 9d5798ff1..b0c93ee26 100644 --- a/src/client/views/PresentationView.tsx +++ b/src/client/views/PresentationView.tsx @@ -1,15 +1,13 @@ +import { action, observable } from "mobx"; import { observer } from "mobx-react"; -import React = require("react"); -import { observable, action, runInAction, reaction } from "mobx"; -import "./PresentationView.scss"; -import { DocumentManager } from "../util/DocumentManager"; -import { Utils } from "../../Utils"; -import { Doc, DocListCast, DocListCastAsync } from "../../new_fields/Doc"; -import { listSpec } from "../../new_fields/Schema"; -import { Cast, NumCast, FieldValue, PromiseValue, StrCast, BoolCast } from "../../new_fields/Types"; +import { Doc, DocListCast } from "../../new_fields/Doc"; import { Id } from "../../new_fields/FieldSymbols"; import { List } from "../../new_fields/List"; -import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils"; +import { listSpec } from "../../new_fields/Schema"; +import { BoolCast, Cast, FieldValue, NumCast, StrCast } from "../../new_fields/Types"; +import { DocumentManager } from "../util/DocumentManager"; +import "./PresentationView.scss"; +import React = require("react"); export interface PresViewProps { Document: Doc; diff --git a/src/client/views/SearchItem.tsx b/src/client/views/SearchItem.tsx index 01c7316d6..6901f60da 100644 --- a/src/client/views/SearchItem.tsx +++ b/src/client/views/SearchItem.tsx @@ -1,13 +1,9 @@ import React = require("react"); -import { Doc } from "../../new_fields/Doc"; -import { DocumentManager } from "../util/DocumentManager"; import { library } from '@fortawesome/fontawesome-svg-core'; import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Cast } from "../../new_fields/Types"; -import { FieldView, FieldViewProps } from './nodes/FieldView'; -import { computed } from "mobx"; -import { IconField } from "../../new_fields/IconField"; +import { Doc } from "../../new_fields/Doc"; +import { DocumentManager } from "../util/DocumentManager"; import { SetupDrag } from "../util/DragManager"; diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index e5b679e24..3288abd90 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -1,12 +1,11 @@ -import { observable, computed, action, trace } from "mobx"; -import React = require("react"); +import { action, observable } from "mobx"; import { observer } from "mobx-react"; +import { Doc } from "../../new_fields/Doc"; +import { List } from "../../new_fields/List"; import './DocumentDecorations.scss'; -import { Template } from "./Templates"; import { DocumentView } from "./nodes/DocumentView"; -import { List } from "../../new_fields/List"; -import { Doc } from "../../new_fields/Doc"; -import { NumCast } from "../../new_fields/Types"; +import { Template } from "./Templates"; +import React = require("react"); const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 734669893..9350dc974 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -1,14 +1,14 @@ import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { ContextMenu } from '../ContextMenu'; -import { FieldViewProps } from '../nodes/FieldView'; -import { Cast, FieldValue, PromiseValue, NumCast } from '../../../new_fields/Types'; -import { Doc, FieldResult, Opt, DocListCast } from '../../../new_fields/Doc'; -import { listSpec } from '../../../new_fields/Schema'; +import { Doc, DocListCast, Opt } from '../../../new_fields/Doc'; +import { Id } from '../../../new_fields/FieldSymbols'; import { List } from '../../../new_fields/List'; +import { listSpec } from '../../../new_fields/Schema'; +import { Cast, FieldValue, NumCast, PromiseValue } from '../../../new_fields/Types'; import { SelectionManager } from '../../util/SelectionManager'; -import { Id } from '../../../new_fields/FieldSymbols'; +import { ContextMenu } from '../ContextMenu'; +import { FieldViewProps } from '../nodes/FieldView'; export enum CollectionViewType { Invalid, diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index dcc1bd95d..8f6c9b1fc 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -1,28 +1,28 @@ import 'golden-layout/src/css/goldenlayout-base.css'; import 'golden-layout/src/css/goldenlayout-dark-theme.css'; -import { action, observable, reaction, Lambda } from "mobx"; +import { action, Lambda, observable, reaction } from "mobx"; import { observer } from "mobx-react"; import * as ReactDOM from 'react-dom'; import Measure from "react-measure"; import * as GoldenLayout from "../../../client/goldenLayout"; -import { Doc, Field, Opt, DocListCast } from "../../../new_fields/Doc"; +import { Doc, DocListCast, Field, Opt } from "../../../new_fields/Doc"; +import { Id } from '../../../new_fields/FieldSymbols'; import { FieldId } from "../../../new_fields/RefField"; import { listSpec } from "../../../new_fields/Schema"; import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; import { emptyFunction, returnTrue, Utils } from "../../../Utils"; import { DocServer } from "../../DocServer"; +import { DocumentManager } from '../../util/DocumentManager'; import { DragLinksAsDocuments, DragManager } from "../../util/DragManager"; +import { SelectionManager } from '../../util/SelectionManager'; import { Transform } from '../../util/Transform'; import { undoBatch, UndoManager } from "../../util/UndoManager"; import { DocumentView } from "../nodes/DocumentView"; +import { CollectionViewType } from './CollectionBaseView'; import "./CollectionDockingView.scss"; import { SubCollectionViewProps } from "./CollectionSubView"; -import React = require("react"); import { ParentDocSelector } from './ParentDocumentSelector'; -import { DocumentManager } from '../../util/DocumentManager'; -import { CollectionViewType } from './CollectionBaseView'; -import { Id } from '../../../new_fields/FieldSymbols'; -import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils'; +import React = require("react"); @observer export class CollectionDockingView extends React.Component { @@ -357,6 +357,7 @@ export class CollectionDockingView extends React.Component; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index be37efd3d..31e662da5 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -1,23 +1,22 @@ -import { action, runInAction } from "mobx"; -import React = require("react"); -import { undoBatch, UndoManager } from "../../util/UndoManager"; -import { DragManager } from "../../util/DragManager"; -import { Docs, DocumentOptions } from "../../documents/Documents"; -import { RouteStore } from "../../../server/RouteStore"; +import { action } from "mobx"; +import * as rp from 'request-promise'; +import CursorField from "../../../new_fields/CursorField"; +import { Doc, DocListCast, Opt } from "../../../new_fields/Doc"; +import { List } from "../../../new_fields/List"; +import { listSpec } from "../../../new_fields/Schema"; +import { Cast, PromiseValue } from "../../../new_fields/Types"; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; +import { RouteStore } from "../../../server/RouteStore"; +import { DocServer } from "../../DocServer"; +import { Docs, DocumentOptions } from "../../documents/Documents"; +import { DragManager } from "../../util/DragManager"; +import { undoBatch, UndoManager } from "../../util/UndoManager"; +import { DocComponent } from "../DocComponent"; import { FieldViewProps } from "../nodes/FieldView"; -import * as rp from 'request-promise'; -import { CollectionView } from "./CollectionView"; import { CollectionPDFView } from "./CollectionPDFView"; import { CollectionVideoView } from "./CollectionVideoView"; -import { Doc, Opt, FieldResult, DocListCast } from "../../../new_fields/Doc"; -import { DocComponent } from "../DocComponent"; -import { listSpec } from "../../../new_fields/Schema"; -import { Cast, PromiseValue, FieldValue, ListSpec } from "../../../new_fields/Types"; -import { List } from "../../../new_fields/List"; -import { DocServer } from "../../DocServer"; -import CursorField from "../../../new_fields/CursorField"; -import { DocumentManager } from "../../util/DocumentManager"; +import { CollectionView } from "./CollectionView"; +import React = require("react"); export interface CollectionViewProps extends FieldViewProps { addDocument: (document: Doc, allowDuplicates?: boolean) => boolean; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 48da52ffa..9fb1da716 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -1,25 +1,24 @@ import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; -import { faCaretDown, faCaretRight, faTrashAlt, faAngleRight } from '@fortawesome/free-solid-svg-icons'; +import { faAngleRight, faCaretDown, faCaretRight, faTrashAlt } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable, trace } from "mobx"; import { observer } from "mobx-react"; -import { DragManager, SetupDrag, dropActionType } from "../../util/DragManager"; -import { EditableView } from "../EditableView"; -import { CollectionSubView } from "./CollectionSubView"; -import "./CollectionTreeView.scss"; -import React = require("react"); -import { Document, listSpec } from '../../../new_fields/Schema'; -import { Cast, StrCast, BoolCast, FieldValue, NumCast } from '../../../new_fields/Types'; import { Doc, DocListCast } from '../../../new_fields/Doc'; import { Id } from '../../../new_fields/FieldSymbols'; -import { ContextMenu } from '../ContextMenu'; -import { undoBatch } from '../../util/UndoManager'; -import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils'; -import { CollectionDockingView } from './CollectionDockingView'; -import { DocumentManager } from '../../util/DocumentManager'; +import { Document, listSpec } from '../../../new_fields/Schema'; +import { BoolCast, Cast, NumCast, StrCast } from '../../../new_fields/Types'; import { Docs } from '../../documents/Documents'; +import { DocumentManager } from '../../util/DocumentManager'; +import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager"; +import { undoBatch } from '../../util/UndoManager'; +import { ContextMenu } from '../ContextMenu'; +import { EditableView } from "../EditableView"; import { MainView } from '../MainView'; import { CollectionViewType } from './CollectionBaseView'; +import { CollectionDockingView } from './CollectionDockingView'; +import { CollectionSubView } from "./CollectionSubView"; +import "./CollectionTreeView.scss"; +import React = require("react"); export interface TreeViewProps { @@ -220,6 +219,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { } } render() { + trace(); let dropAction = StrCast(this.props.Document.dropAction, "alias") as dropActionType; if (!this.childDocs) { return (null); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 301b769af..ca7c99f28 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -1,11 +1,10 @@ import { observer } from "mobx-react"; -import { Utils } from "../../../../Utils"; +import { Doc, HeightSym, WidthSym } from "../../../../new_fields/Doc"; +import { BoolCast, NumCast, StrCast } from "../../../../new_fields/Types"; +import { InkingControl } from "../../InkingControl"; import "./CollectionFreeFormLinkView.scss"; import React = require("react"); import v5 = require("uuid/v5"); -import { StrCast, NumCast, BoolCast } from "../../../../new_fields/Types"; -import { Doc, WidthSym, HeightSym } from "../../../../new_fields/Doc"; -import { InkingControl } from "../../InkingControl"; export interface CollectionFreeFormLinkViewProps { A: Doc; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx index a43c5f241..c4dd534ed 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx @@ -1,17 +1,16 @@ -import { computed, IReactionDisposer, reaction, trace } from "mobx"; +import { computed, IReactionDisposer, reaction } from "mobx"; import { observer } from "mobx-react"; -import { Utils } from "../../../../Utils"; +import { Doc, DocListCast } from "../../../../new_fields/Doc"; +import { Id } from "../../../../new_fields/FieldSymbols"; +import { List } from "../../../../new_fields/List"; +import { listSpec } from "../../../../new_fields/Schema"; +import { Cast, FieldValue, NumCast, StrCast } from "../../../../new_fields/Types"; import { DocumentManager } from "../../../util/DocumentManager"; import { DocumentView } from "../../nodes/DocumentView"; import { CollectionViewProps } from "../CollectionSubView"; import "./CollectionFreeFormLinksView.scss"; import { CollectionFreeFormLinkView } from "./CollectionFreeFormLinkView"; import React = require("react"); -import { Doc, DocListCastAsync, DocListCast } from "../../../../new_fields/Doc"; -import { Cast, FieldValue, NumCast, StrCast } from "../../../../new_fields/Types"; -import { listSpec } from "../../../../new_fields/Schema"; -import { List } from "../../../../new_fields/List"; -import { Id } from "../../../../new_fields/FieldSymbols"; @observer export class CollectionFreeFormLinksView extends React.Component { @@ -110,7 +109,6 @@ export class CollectionFreeFormLinksView extends React.Component { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9d19df540..2b43c76c6 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,8 +1,15 @@ -import { action, computed, trace } from "mobx"; +import { action, computed } from "mobx"; import { observer } from "mobx-react"; -import { emptyFunction, returnFalse, returnOne } from "../../../../Utils"; +import { Doc, HeightSym, WidthSym } from "../../../../new_fields/Doc"; +import { Id } from "../../../../new_fields/FieldSymbols"; +import { InkField, StrokeData } from "../../../../new_fields/InkField"; +import { createSchema, makeInterface } from "../../../../new_fields/Schema"; +import { BoolCast, Cast, FieldValue, NumCast } from "../../../../new_fields/Types"; +import { emptyFunction, returnOne } from "../../../../Utils"; +import { DocServer } from "../../../DocServer"; import { DocumentManager } from "../../../util/DocumentManager"; import { DragManager } from "../../../util/DragManager"; +import { HistoryUtil } from "../../../util/History"; import { SelectionManager } from "../../../util/SelectionManager"; import { Transform } from "../../../util/Transform"; import { undoBatch } from "../../../util/UndoManager"; @@ -11,6 +18,7 @@ import { InkingCanvas } from "../../InkingCanvas"; import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView"; import { DocumentContentsView } from "../../nodes/DocumentContentsView"; import { DocumentViewProps, positionSchema } from "../../nodes/DocumentView"; +import { pageSchema } from "../../nodes/ImageBox"; import { CollectionSubView } from "../CollectionSubView"; import { CollectionFreeFormLinksView } from "./CollectionFreeFormLinksView"; import { CollectionFreeFormRemoteCursors } from "./CollectionFreeFormRemoteCursors"; @@ -18,14 +26,6 @@ import "./CollectionFreeFormView.scss"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); import v5 = require("uuid/v5"); -import { createSchema, makeInterface, listSpec } from "../../../../new_fields/Schema"; -import { Doc, WidthSym, HeightSym } from "../../../../new_fields/Doc"; -import { FieldValue, Cast, NumCast, BoolCast } from "../../../../new_fields/Types"; -import { pageSchema } from "../../nodes/ImageBox"; -import { InkField, StrokeData } from "../../../../new_fields/InkField"; -import { HistoryUtil } from "../../../util/History"; -import { Id } from "../../../../new_fields/FieldSymbols"; -import { DocServer } from "../../../DocServer"; export const panZoomSchema = createSchema({ panX: "number", diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 29734fa19..9ec941eff 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -1,27 +1,25 @@ import * as htmlToImage from "html-to-image"; -import { action, computed, observable, trace } from "mobx"; +import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; +import { Doc } from "../../../../new_fields/Doc"; +import { Id } from "../../../../new_fields/FieldSymbols"; +import { InkField, StrokeData } from "../../../../new_fields/InkField"; +import { List } from "../../../../new_fields/List"; +import { Cast, NumCast } from "../../../../new_fields/Types"; +import { Utils } from "../../../../Utils"; +import { DocServer } from "../../../DocServer"; import { Docs } from "../../../documents/Documents"; import { SelectionManager } from "../../../util/SelectionManager"; import { Transform } from "../../../util/Transform"; -import { undoBatch, UndoManager } from "../../../util/UndoManager"; +import { undoBatch } from "../../../util/UndoManager"; import { InkingCanvas } from "../../InkingCanvas"; import { PreviewCursor } from "../../PreviewCursor"; +import { SearchBox } from "../../SearchBox"; +import { Templates } from "../../Templates"; +import { CollectionViewType } from "../CollectionBaseView"; import { CollectionFreeFormView } from "./CollectionFreeFormView"; import "./MarqueeView.scss"; import React = require("react"); -import { Utils } from "../../../../Utils"; -import { Doc } from "../../../../new_fields/Doc"; -import { NumCast, Cast } from "../../../../new_fields/Types"; -import { InkField, StrokeData } from "../../../../new_fields/InkField"; -import { List } from "../../../../new_fields/List"; -import { ImageField } from "../../../../new_fields/URLField"; -import { Template, Templates } from "../../Templates"; -import { SearchBox } from "../../SearchBox"; -import { DocServer } from "../../../DocServer"; -import { Id } from "../../../../new_fields/FieldSymbols"; -import { CollectionView } from "../CollectionView"; -import { CollectionViewType } from "../CollectionBaseView"; interface MarqueeViewProps { getContainerTransform: () => Transform; diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 7b642b299..5a83de8e3 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -1,24 +1,23 @@ import React = require("react"); +import { computed } from "mobx"; import { observer } from "mobx-react"; -import { computed, observable } from "mobx"; -import { FormattedTextBox } from "./FormattedTextBox"; -import { ImageBox } from "./ImageBox"; -import { VideoBox } from "./VideoBox"; -import { AudioBox } from "./AudioBox"; -import { DocumentContentsView } from "./DocumentContentsView"; +import { DateField } from "../../../new_fields/DateField"; +import { Doc, FieldResult, Opt } from "../../../new_fields/Doc"; +import { IconField } from "../../../new_fields/IconField"; +import { List } from "../../../new_fields/List"; +import { RichTextField } from "../../../new_fields/RichTextField"; +import { AudioField, ImageField, VideoField } from "../../../new_fields/URLField"; +import { emptyFunction, returnFalse, returnOne } from "../../../Utils"; import { Transform } from "../../util/Transform"; -import { returnFalse, emptyFunction, returnOne } from "../../../Utils"; -import { CollectionView } from "../collections/CollectionView"; import { CollectionPDFView } from "../collections/CollectionPDFView"; import { CollectionVideoView } from "../collections/CollectionVideoView"; +import { CollectionView } from "../collections/CollectionView"; +import { AudioBox } from "./AudioBox"; +import { DocumentContentsView } from "./DocumentContentsView"; +import { FormattedTextBox } from "./FormattedTextBox"; import { IconBox } from "./IconBox"; -import { Opt, Doc, FieldResult } from "../../../new_fields/Doc"; -import { List } from "../../../new_fields/List"; -import { ImageField, VideoField, AudioField } from "../../../new_fields/URLField"; -import { IconField } from "../../../new_fields/IconField"; -import { RichTextField } from "../../../new_fields/RichTextField"; -import { DateField } from "../../../new_fields/DateField"; -import { NumCast } from "../../../new_fields/Types"; +import { ImageBox } from "./ImageBox"; +import { VideoBox } from "./VideoBox"; // diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 5c635cc0c..53ab7c35e 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -7,11 +7,12 @@ import { history } from "prosemirror-history"; import { keymap } from "prosemirror-keymap"; import { EditorState, Plugin, Transaction } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; -import { Doc, Field, Opt, WidthSym, HeightSym } from "../../../new_fields/Doc"; +import { Doc, Opt } from "../../../new_fields/Doc"; import { RichTextField } from "../../../new_fields/RichTextField"; import { createSchema, makeInterface } from "../../../new_fields/Schema"; import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; import { DocServer } from "../../DocServer"; +import { DocUtils } from '../../documents/Documents'; import { DocumentManager } from "../../util/DocumentManager"; import { DragManager } from "../../util/DragManager"; import buildKeymap from "../../util/ProsemirrorKeymap"; @@ -21,14 +22,11 @@ import { SelectionManager } from "../../util/SelectionManager"; import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu"; import { TooltipTextMenu } from "../../util/TooltipTextMenu"; import { undoBatch, UndoManager } from "../../util/UndoManager"; -import { ContextMenu } from "../../views/ContextMenu"; -import { CollectionDockingView } from "../collections/CollectionDockingView"; import { DocComponent } from "../DocComponent"; import { InkingControl } from "../InkingControl"; import { FieldView, FieldViewProps } from "./FieldView"; import "./FormattedTextBox.scss"; import React = require("react"); -import { DocUtils } from '../../documents/Documents'; library.add(faEdit); library.add(faSmile); diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 4c2b73b70..06ecc794b 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,25 +1,25 @@ -import { action, observable, trace } from 'mobx'; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faImage } from '@fortawesome/free-solid-svg-icons'; +import { action, observable } from 'mobx'; import { observer } from "mobx-react"; import Lightbox from 'react-image-lightbox'; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app +import { Doc, HeightSym, WidthSym } from '../../../new_fields/Doc'; +import { List } from '../../../new_fields/List'; +import { createSchema, listSpec, makeInterface } from '../../../new_fields/Schema'; +import { Cast, FieldValue, NumCast, StrCast } from '../../../new_fields/Types'; +import { ImageField } from '../../../new_fields/URLField'; import { Utils } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from "../../views/ContextMenu"; +import { ContextMenuProps } from '../ContextMenuItem'; +import { DocComponent } from '../DocComponent'; +import { InkingControl } from '../InkingControl'; +import { positionSchema } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import "./ImageBox.scss"; import React = require("react"); -import { createSchema, makeInterface, listSpec } from '../../../new_fields/Schema'; -import { DocComponent } from '../DocComponent'; -import { positionSchema } from './DocumentView'; -import { FieldValue, Cast, StrCast, PromiseValue, NumCast } from '../../../new_fields/Types'; -import { ImageField } from '../../../new_fields/URLField'; -import { List } from '../../../new_fields/List'; -import { InkingControl } from '../InkingControl'; -import { Doc, WidthSym, HeightSym } from '../../../new_fields/Doc'; -import { faImage } from '@fortawesome/free-solid-svg-icons'; -import { library } from '@fortawesome/fontawesome-svg-core'; -import { ContextMenuItemProps, ContextMenuProps } from '../ContextMenuItem'; var path = require('path'); diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 35ecf12f6..1239b498f 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -1,19 +1,17 @@ import React = require("react"); +import { action, IReactionDisposer, observable, reaction } from "mobx"; import { observer } from "mobx-react"; -import { FieldView, FieldViewProps } from './FieldView'; import * as rp from "request-promise"; -import "./VideoBox.scss"; -import { action, IReactionDisposer, reaction, observable } from "mobx"; -import { DocComponent } from "../DocComponent"; -import { positionSchema } from "./DocumentView"; import { makeInterface } from "../../../new_fields/Schema"; -import { pageSchema } from "./ImageBox"; -import { Cast, FieldValue, NumCast } from "../../../new_fields/Types"; +import { Cast, FieldValue } from "../../../new_fields/Types"; import { VideoField } from "../../../new_fields/URLField"; -import "./VideoBox.scss"; import { RouteStore } from "../../../server/RouteStore"; import { DocServer } from "../../DocServer"; -import { actionFieldDecorator } from "mobx/lib/internal"; +import { DocComponent } from "../DocComponent"; +import { positionSchema } from "./DocumentView"; +import { FieldView, FieldViewProps } from './FieldView'; +import { pageSchema } from "./ImageBox"; +import "./VideoBox.scss"; type VideoDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>; const VideoDocument = makeInterface(positionSchema, pageSchema); diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 2239a8e38..98c57fc75 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -1,12 +1,11 @@ -import "./WebBox.scss"; -import React = require("react"); -import { FieldViewProps, FieldView } from './FieldView'; +import { observer } from "mobx-react"; import { HtmlField } from "../../../new_fields/HtmlField"; import { WebField } from "../../../new_fields/URLField"; -import { observer } from "mobx-react"; -import { computed, reaction, IReactionDisposer } from 'mobx'; import { DocumentDecorations } from "../DocumentDecorations"; import { InkingControl } from "../InkingControl"; +import { FieldView, FieldViewProps } from './FieldView'; +import "./WebBox.scss"; +import React = require("react"); @observer export class WebBox extends React.Component { -- cgit v1.2.3-70-g09d2 From 1087133d71ef2ac7df6976c61685167ed0fe71d9 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 5 Jun 2019 14:09:40 -0400 Subject: cleaned up selections somewhat so that PDFs don't flicker when manipulating annotations. --- src/client/util/SelectionManager.ts | 24 +++++++++------------- src/client/views/DocumentDecorations.tsx | 1 - .../views/collections/CollectionBaseView.tsx | 2 +- src/client/views/collections/CollectionPDFView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 1 - .../collections/collectionFreeForm/MarqueeView.tsx | 1 - src/client/views/nodes/PDFBox.tsx | 16 +++++++-------- 7 files changed, 20 insertions(+), 27 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 8c92c2023..5311841e1 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -21,6 +21,13 @@ export namespace SelectionManager { doc.props.whenActiveChanged(true); } } + @action + DeSelectDoc(doc: DocumentView): void { + if (manager.SelectedDocuments.indexOf(doc) !== -1) { + manager.SelectedDocuments.splice(manager.SelectedDocuments.indexOf(doc), 1); + doc.props.whenActiveChanged(false); + } + } @action DeselectAll(): void { @@ -28,16 +35,6 @@ export namespace SelectionManager { manager.SelectedDocuments = []; FormattedTextBox.InputBoxOverlay = undefined; } - @action - ReselectAll() { - let sdocs = manager.SelectedDocuments.map(d => d); - manager.SelectedDocuments = []; - return sdocs; - } - @action - ReselectAll2(sdocs: DocumentView[]) { - sdocs.map(s => SelectionManager.SelectDoc(s, true)); - } } const manager = new Manager(); @@ -49,6 +46,9 @@ export namespace SelectionManager { export function IsSelected(doc: DocumentView): boolean { return manager.SelectedDocuments.indexOf(doc) !== -1; } + export function DeSelectDoc(doc: DocumentView): void { + manager.DeSelectDoc(doc); + } export function DeselectAll(except?: Doc): void { let found: DocumentView | undefined = undefined; @@ -62,10 +62,6 @@ export namespace SelectionManager { if (found) manager.SelectDoc(found, false); } - export function ReselectAll() { - let sdocs = manager.ReselectAll(); - setTimeout(() => manager.ReselectAll2(sdocs), 0); - } export function SelectedDocuments(): Array { return manager.SelectedDocuments; } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 37895516a..cdd537760 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -463,7 +463,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> e.stopPropagation(); this._resizing = ""; this.Interacting = false; - SelectionManager.ReselectAll(); if (e.button === 0) { e.preventDefault(); this._isPointerDown = false; diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 9350dc974..cb92464e5 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -158,7 +158,7 @@ export class CollectionBaseView extends React.Component { @action.bound moveDocument(doc: Doc, targetCollection: Doc, addDocument: (doc: Doc) => boolean): boolean { - if (this.props.Document === targetCollection) { + if (Doc.AreProtosEqual(this.props.Document, targetCollection)) { return true; } if (this.removeDocument(doc)) { diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx index 5e51437a4..25c1535b3 100644 --- a/src/client/views/collections/CollectionPDFView.tsx +++ b/src/client/views/collections/CollectionPDFView.tsx @@ -70,7 +70,7 @@ export class CollectionPDFView extends React.Component { return ( <> - {this.props.isSelected() ? this.uIButtons : (null)} + {this.props.active() ? this.uIButtons : (null)} ); } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 634b4dfa0..582f93c2e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -104,7 +104,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } this.bringToFront(d); }); - SelectionManager.ReselectAll(); } return true; } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 9ec941eff..81ca4c29a 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -325,7 +325,6 @@ export class MarqueeView extends React.Component } else { this.props.addDocument(newCollection, false); - SelectionManager.DeselectAll(); this.props.selectDocuments([newCollection]); } this.cleanupInteractions(false); diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index aa29a7170..855c744e6 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -68,20 +68,21 @@ export class PDFBox extends DocComponent(PdfDocumen @observable private _currAnno: any = []; @observable private _interactive: boolean = false; - @observable private _loaded: boolean = false; @computed private get curPage() { return NumCast(this.Document.curPage, 1); } @computed private get thumbnailPage() { return NumCast(this.props.Document.thumbnailPage, -1); } componentDidMount() { - let wasSelected = this.props.isSelected(); + let wasSelected = this.props.active(); this._reactionDisposer = reaction( - () => [this.props.isSelected(), this.curPage], + () => [this.props.active(), this.curPage], () => { - if (this.curPage > 0 && !this.props.isTopMost && this.curPage !== this.thumbnailPage && wasSelected && !this.props.isSelected()) { - this.saveThumbnail(); - } - wasSelected = this._interactive = this.props.isSelected(); + setTimeout(action(() => { // this forces the active() check to happen after all changes in a transaction have occurred. + if (this.curPage > 0 && !this.props.isTopMost && this.curPage !== this.thumbnailPage && wasSelected && !this.props.active()) { + this.saveThumbnail(); + } + wasSelected = this._interactive = this.props.active(); + }), 0); }, { fireImmediately: true }); @@ -276,7 +277,6 @@ export class PDFBox extends DocComponent(PdfDocumen if (this._perPageInfo.length === 0) { //Makes sure it only runs once this._perPageInfo = [...Array(page._transport.numPages)]; } - this._loaded = true; } @action -- cgit v1.2.3-70-g09d2 From ac63044fad5968cca83108f6dd3015ef657840bd Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 7 Jun 2019 10:21:55 -0400 Subject: fixed some pinterest layout issues. --- .../views/collections/CollectionBaseView.scss | 11 ++++++++ .../views/collections/CollectionBaseView.tsx | 4 +-- .../views/collections/CollectionStackingView.scss | 20 ++++--------- .../views/collections/CollectionStackingView.tsx | 33 +++++++++++----------- src/client/views/nodes/DocumentView.tsx | 3 +- 5 files changed, 36 insertions(+), 35 deletions(-) create mode 100644 src/client/views/collections/CollectionBaseView.scss (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/collections/CollectionBaseView.scss b/src/client/views/collections/CollectionBaseView.scss new file mode 100644 index 000000000..1f5acb96a --- /dev/null +++ b/src/client/views/collections/CollectionBaseView.scss @@ -0,0 +1,11 @@ +@import "../globalCssVariables"; +#collectionBaseView { + border-width: 0; + box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw; + border-color: $light-color-secondary; + border-style: solid; + border-radius: 0 0 $border-radius $border-radius; + box-sizing: border-box; + border-radius: inherit; + pointer-events: all; +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index cb92464e5..ddec587a9 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -9,6 +9,7 @@ import { Cast, FieldValue, NumCast, PromiseValue } from '../../../new_fields/Typ import { SelectionManager } from '../../util/SelectionManager'; import { ContextMenu } from '../ContextMenu'; import { FieldViewProps } from '../nodes/FieldView'; +import './CollectionBaseView.scss'; export enum CollectionViewType { Invalid, @@ -178,8 +179,7 @@ export class CollectionBaseView extends React.Component { }; const viewtype = this.collectionViewType; return ( -
{viewtype !== undefined ? this.props.children(viewtype, props) : (null)}
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss index 4d84aaaa9..af194aec9 100644 --- a/src/client/views/collections/CollectionStackingView.scss +++ b/src/client/views/collections/CollectionStackingView.scss @@ -1,19 +1,6 @@ @import "../globalCssVariables"; - .collectionStackingView { - top: 0; - left: 0; - display: flex; - flex-direction: column; - width: 100%; - position: absolute; overflow-y: auto; - border-width: 0; - box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw; - border-color: $light-color-secondary; - border-style: solid; - border-radius: 0 0 $border-radius $border-radius; - box-sizing: border-box; .collectionStackingView-docView-container { width: 45%; @@ -33,9 +20,12 @@ width:100%; height:100%; position: absolute; - } - .collectionStackingView-masonryGrid { display:grid; + top: 0; + left: 0; + width: 100%; + position: absolute; + } .collectionStackingView-description { diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index eeae498a6..b8eb4ac84 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -32,11 +32,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { return (nw && nh) ? wid * aspect : d[HeightSym](); } componentDidMount() { - this._heightDisposer = reaction(() => [this.yMargin, this.columnWidth, this.childDocs.map(d => [d.height, d.width, d.zoomBasis, d.nativeHeight, d.nativeWidth, d.isMinimized])], + this._heightDisposer = reaction(() => [this.yMargin, this.gridGap, this.columnWidth, this.childDocs.map(d => [d.height, d.width, d.zoomBasis, d.nativeHeight, d.nativeWidth, d.isMinimized])], () => { if (this.singleColumn) { - this.props.Document.height = this.childDocs.filter(d => !d.isMinimized).reduce((height, d) => - height + this.singleColDocHeight(d) + this.yMargin + let children = this.childDocs.filter(d => !d.isMinimized); + this.props.Document.height = children.reduce((height, d, i) => + height + this.singleColDocHeight(d) + (i === children.length - 1 ? this.yMargin : this.gridGap) , this.yMargin); } }, { fireImmediately: true }); @@ -78,7 +79,8 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { @computed get singleColumnChildren() { - return this.childDocs.filter(d => !d.isMinimized).map((d, i) => { + let children = this.childDocs.filter(d => !d.isMinimized); + return children.map((d, i) => { let dref = React.createRef(); let script = undefined; let colWidth = () => d.nativeWidth ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth; @@ -87,7 +89,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { return
+ style={{ width: colWidth(), height: rowHeight(), marginLeft: "auto", marginRight: "auto" }} > doc) { } @computed get children() { + trace(); return this.childDocs.filter(d => !d.isMinimized).map((d, i) => { let dref = React.createRef(); let dxf = () => this.getDocTransform(d, dref.current!); - let colSpan = 1;//Math.ceil((this.columnWidth + this.gridGap) / (this._gridSize + this.gridGap)); let rowSpan = Math.ceil((this.columnWidth / d[WidthSym]() * d[HeightSym]() + this.gridGap) / (this._gridSize + this.gridGap)); let childFocus = (doc: Doc) => { doc.libraryBrush = true; @@ -124,7 +126,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { height: NumCast(d.nativeHeight, d[HeightSym]()), transformOrigin: "top left", gridRowEnd: `span ${rowSpan}`, - gridColumnEnd: `span ${colSpan}`, + gridColumnEnd: `span 1`, transform: `scale(${this.columnWidth / NumCast(d.nativeWidth, d[WidthSym]())}, ${this.columnWidth / NumCast(d.nativeWidth, d[WidthSym]())})` }} > doc) { } } render() { - let cols = this.singleColumn ? 1 : Math.min(this.childDocs.filter(d => !d.isMinimized).length, - Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + 2 * this.gridGap))); + let cols = this.singleColumn ? 1 : Math.max(1, Math.min(this.childDocs.filter(d => !d.isMinimized).length, + Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap)))); let templatecols = ""; for (let i = 0; i < cols; i++) templatecols += `${this.columnWidth}px `; return ( -
e.stopPropagation()}> +
e.stopPropagation()} style={{ - padding: `${this.yMargin}px ${this.xMargin}px 0px ${this.xMargin}px`, + padding: this.singleColumn ? `${this.yMargin}px ${this.xMargin}px ${this.yMargin}px ${this.xMargin}px` : `${this.yMargin}px ${this.xMargin}px`, margin: "auto", - width: this.singleColumn ? undefined : `${cols * (this.columnWidth + this.gridGap)}px`, + width: this.singleColumn ? undefined : `${cols * (this.columnWidth + this.gridGap) + 2 * this.xMargin - this.gridGap}px`, height: "100%", position: "relative", gridGap: this.gridGap, @@ -178,8 +180,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { }} > {this.singleColumn ? this.singleColumnChildren : this.children} -
-
+
); } } \ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 36a5358f0..ff2b9842f 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,6 +1,6 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { faAlignCenter, faCaretSquareRight, faCompressArrowsAlt, faExpandArrowsAlt, faLayerGroup, faSquare, faTrash, faConciergeBell, faFolder, faMapPin, faLink, faFingerprint, faCrosshairs, faDesktop } from '@fortawesome/free-solid-svg-icons'; -import { action, computed, IReactionDisposer, reaction } from "mobx"; +import { action, computed, IReactionDisposer, reaction, trace } from "mobx"; import { observer } from "mobx-react"; import { Doc, DocListCast, HeightSym, Opt, WidthSym, DocListCastAsync } from "../../../new_fields/Doc"; import { List } from "../../../new_fields/List"; @@ -439,7 +439,6 @@ export class DocumentView extends DocComponent(Docu var scaling = this.props.ContentScaling(); var nativeHeight = this.nativeHeight > 0 ? `${this.nativeHeight}px` : "100%"; var nativeWidth = this.nativeWidth > 0 ? `${this.nativeWidth}px` : "100%"; - return (
Date: Sun, 9 Jun 2019 20:32:06 -0400 Subject: added a link context for link targets. --- src/client/documents/Documents.ts | 30 ++++++++++------------ src/client/util/DocumentManager.ts | 29 ++++++++++++++++----- src/client/views/DocumentDecorations.tsx | 3 +-- .../views/collections/CollectionBaseView.tsx | 6 ++--- .../views/collections/CollectionStackingView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 15 ++++++++--- 6 files changed, 52 insertions(+), 33 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f0fb0c3ed..2ae127e21 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -69,31 +69,27 @@ export interface DocumentOptions { const delegateKeys = ["x", "y", "width", "height", "panX", "panY"]; export namespace DocUtils { - export function MakeLink(source: Doc, target: Doc) { + export function MakeLink(source: Doc, target: Doc, targetContext?: Doc) { let protoSrc = source.proto ? source.proto : source; let protoTarg = target.proto ? target.proto : target; UndoManager.RunInBatch(() => { let linkDoc = Docs.TextDocument({ width: 100, height: 30, borderRounding: -1 }); - //let linkDoc = new Doc; - linkDoc.proto!.title = "-link name-"; - linkDoc.proto!.linkDescription = ""; - linkDoc.proto!.linkTags = "Default"; + let linkDocProto = Doc.GetProto(linkDoc); + linkDocProto.title = source.title + " to " + target.title; + linkDocProto.linkDescription = ""; + linkDocProto.linkTags = "Default"; - linkDoc.proto!.linkedTo = target; - linkDoc.proto!.linkedToPage = target.curPage; - linkDoc.proto!.linkedFrom = source; - linkDoc.proto!.linkedFromPage = source.curPage; + linkDocProto.linkedTo = target; + linkDocProto.linkedFrom = source; + linkDocProto.linkedToPage = target.curPage; + linkDocProto.linkedFromPage = source.curPage; + linkDocProto.linkedToContext = targetContext; let linkedFrom = Cast(protoTarg.linkedFromDocs, listSpec(Doc)); - if (!linkedFrom) { - protoTarg.linkedFromDocs = linkedFrom = new List(); - } - linkedFrom.push(linkDoc); - let linkedTo = Cast(protoSrc.linkedToDocs, listSpec(Doc)); - if (!linkedTo) { - protoSrc.linkedToDocs = linkedTo = new List(); - } + !linkedFrom && (protoTarg.linkedFromDocs = linkedFrom = new List()); + !linkedTo && (protoSrc.linkedToDocs = linkedTo = new List()); + linkedFrom.push(linkDoc); linkedTo.push(linkDoc); return linkDoc; }, "make link"); diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 65c4b9e4b..ff0c1560b 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -115,7 +115,7 @@ export class DocumentManager { } @undoBatch - public jumpToDocument = async (docDelegate: Doc, forceDockFunc: boolean = false, dockFunc?: (doc: Doc) => void, linkPage?: number): Promise => { + public jumpToDocument = async (docDelegate: Doc, forceDockFunc: boolean = false, dockFunc?: (doc: Doc) => void, linkPage?: number, docContext?: Doc): Promise => { let doc = Doc.GetProto(docDelegate); const contextDoc = await Cast(doc.annotationOn, Doc); if (contextDoc) { @@ -123,6 +123,7 @@ export class DocumentManager { const curPage = NumCast(contextDoc.curPage, page); if (page !== curPage) contextDoc.curPage = page; } + let docView: DocumentView | null; // using forceDockFunc as a flag for splitting linked to doc to the right...can change later if needed if (!forceDockFunc && (docView = DocumentManager.Instance.getDocumentView(doc))) { @@ -131,18 +132,34 @@ export class DocumentManager { docView.props.focus(docView.props.Document); } else { if (!contextDoc) { - const actualDoc = Doc.MakeAlias(docDelegate); - actualDoc.libraryBrush = true; - if (linkPage !== undefined) actualDoc.curPage = linkPage; - (dockFunc || CollectionDockingView.Instance.AddRightSplit)(actualDoc); + if (docContext) { + let targetContextView: DocumentView | null; + if (!forceDockFunc && docContext && (targetContextView = DocumentManager.Instance.getDocumentView(docContext))) { + docContext.panTransformType = "Ease"; + targetContextView.props.focus(docDelegate); + } else { + (dockFunc || CollectionDockingView.Instance.AddRightSplit)(docContext); + setTimeout(() => { + this.jumpToDocument(docDelegate, forceDockFunc, dockFunc, linkPage); + }, 10); + } + } else { + const actualDoc = Doc.MakeAlias(docDelegate); + actualDoc.libraryBrush = true; + if (linkPage !== undefined) actualDoc.curPage = linkPage; + (dockFunc || CollectionDockingView.Instance.AddRightSplit)(actualDoc); + } } else { let contextView: DocumentView | null; docDelegate.libraryBrush = true; if (!forceDockFunc && (contextView = DocumentManager.Instance.getDocumentView(contextDoc))) { contextDoc.panTransformType = "Ease"; - contextView.props.focus(contextDoc); + contextView.props.focus(docDelegate); } else { (dockFunc || CollectionDockingView.Instance.AddRightSplit)(contextDoc); + setTimeout(() => { + this.jumpToDocument(docDelegate, forceDockFunc, dockFunc, linkPage); + }, 10); } } } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index f22fecb98..7260b00cf 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -432,7 +432,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (rect.width !== 0 && (dX != 0 || dY != 0 || dW != 0 || dH != 0)) { let doc = PositionDocument(element.props.Document); - let docHeightBefore = doc.height; let nwidth = doc.nativeWidth || 0; let nheight = doc.nativeHeight || 0; let zoomBasis = NumCast(doc.zoomBasis, 1); @@ -469,7 +468,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } } else { doc.width = zoomBasis * actualdW; - if (docHeightBefore === doc.height) doc.height = zoomBasis * actualdH; + doc.height = zoomBasis * actualdH; } } }); diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index ddec587a9..d120c3a0c 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -101,9 +101,9 @@ export class CollectionBaseView extends React.Component { addDocument(doc: Doc, allowDuplicates: boolean = false): boolean { let props = this.props; var curPage = NumCast(props.Document.curPage, -1); - Doc.SetOnPrototype(doc, "page", curPage); + Doc.GetProto(doc).page = curPage; if (curPage >= 0) { - Doc.SetOnPrototype(doc, "annotationOn", props.Document); + Doc.GetProto(doc).annotationOn = props.Document; } if (!this.createsCycle(doc, props.Document)) { //TODO This won't create the field if it doesn't already exist @@ -141,7 +141,7 @@ export class CollectionBaseView extends React.Component { break; } } - PromiseValue(Cast(doc.annotationOn, Doc)).then((annotationOn) => { + PromiseValue(Cast(doc.annotationOn, Doc)).then(annotationOn => { if (annotationOn === props.Document) { doc.annotationOn = undefined; } diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 0a119a3b4..cad7cd50c 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -153,7 +153,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { 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 ContextMenu.Instance.addItem({ description: "Toggle multi-column", - event: () => this.props.Document.singleColumn = !BoolCast(this.props.Document.singleColumn, false), icon: "file-pdf" + event: () => this.props.Document.singleColumn = !BoolCast(this.props.Document.singleColumn, true), icon: "file-pdf" }); } } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 85b8a5596..2ac6d12bf 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -6,7 +6,7 @@ import { Doc, DocListCast, HeightSym, Opt, WidthSym, DocListCastAsync } from ".. import { List } from "../../../new_fields/List"; import { ObjectField } from "../../../new_fields/ObjectField"; import { createSchema, makeInterface } from "../../../new_fields/Schema"; -import { BoolCast, Cast, FieldValue, StrCast, NumCast } from "../../../new_fields/Types"; +import { BoolCast, Cast, FieldValue, StrCast, NumCast, PromiseValue } from "../../../new_fields/Types"; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; import { emptyFunction, Utils } from "../../../Utils"; import { DocServer } from "../../DocServer"; @@ -261,12 +261,17 @@ export class DocumentView extends DocComponent(Docu linkedToDocs.length ? linkedToDocs[0].linkedTo as Doc : linkedFromDocs.length ? linkedFromDocs[0].linkedFrom as Doc : expandedDocs[0], linkedFromDocs.length ? linkedFromDocs[0].linkedFrom as Doc : linkedToDocs.length ? linkedToDocs[0].linkedTo as Doc : expandedDocs[0]]; + let linkedFwdContextDocs = [ + linkedToDocs.length ? await (linkedToDocs[0].linkedToContext) as Doc : linkedFromDocs.length ? await PromiseValue(linkedFromDocs[0].linkedFromContext) as Doc : undefined, + linkedFromDocs.length ? await (linkedFromDocs[0].linkedFromContext) as Doc : linkedToDocs.length ? await PromiseValue(linkedToDocs[0].linkedToContext) as Doc : undefined]; + let linkedFwdPage = [ linkedToDocs.length ? NumCast(linkedToDocs[0].linkedToPage, undefined) : linkedFromDocs.length ? NumCast(linkedFromDocs[0].linkedFromPage, undefined) : undefined, linkedFromDocs.length ? NumCast(linkedFromDocs[0].linkedFromPage, undefined) : linkedToDocs.length ? NumCast(linkedToDocs[0].linkedToPage, undefined) : undefined]; + if (!linkedFwdDocs.some(l => l instanceof Promise)) { let maxLocation = StrCast(linkedFwdDocs[altKey ? 1 : 0].maximizeLocation, "inTab"); - DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, document => this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey ? 1 : 0]); + DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, document => this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey ? 1 : 0], linkedFwdContextDocs[altKey ? 1 : 0]); } } } @@ -333,6 +338,7 @@ export class DocumentView extends DocComponent(Docu let sourceDoc = de.data.linkSourceDocument; let destDoc = this.props.Document; + e.stopPropagation(); if (de.mods === "AltKey") { const protoDest = destDoc.proto; const protoSrc = sourceDoc.proto; @@ -343,10 +349,11 @@ export class DocumentView extends DocComponent(Docu dst.nativeHeight = src.nativeHeight; } else { - DocUtils.MakeLink(sourceDoc, destDoc); + const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true); + const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView); + DocUtils.MakeLink(sourceDoc, destDoc, views.length ? views[0].props.Document : undefined); de.data.droppedDocuments.push(destDoc); } - e.stopPropagation(); } } -- cgit v1.2.3-70-g09d2 From 06d5bb5c65da6f4a115ebf8118989115420bccef Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 11 Jun 2019 10:21:42 -0400 Subject: cleaned up some drop() code with text. fixed linkview titling. changed dragging to not deselect source collection. --- src/client/util/SelectionManager.ts | 23 ++++++++++++++++------ .../views/collections/CollectionBaseView.tsx | 5 +++-- .../CollectionFreeFormLinkView.tsx | 5 +++-- src/client/views/nodes/FormattedTextBox.tsx | 22 --------------------- 4 files changed, 23 insertions(+), 32 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index ddad4b818..b26032b04 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -10,15 +10,23 @@ export namespace SelectionManager { @observable SelectedDocuments: Array = []; @action - SelectDoc(doc: DocumentView, ctrlPressed: boolean): void { + SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { // if doc is not in SelectedDocuments, add it if (!ctrlPressed) { this.DeselectAll(); } - if (manager.SelectedDocuments.indexOf(doc) === -1) { - manager.SelectedDocuments.push(doc); - doc.props.whenActiveChanged(true); + if (manager.SelectedDocuments.indexOf(docView) === -1) { + manager.SelectedDocuments.push(docView); + docView.props.whenActiveChanged(true); + } + } + @action + DeselectDoc(docView: DocumentView): void { + let ind = manager.SelectedDocuments.indexOf(docView); + if (ind !== -1) { + manager.SelectedDocuments.splice(ind, 1); + docView.props.whenActiveChanged(false); } } @action @@ -31,8 +39,11 @@ export namespace SelectionManager { const manager = new Manager(); - export function SelectDoc(doc: DocumentView, ctrlPressed: boolean): void { - manager.SelectDoc(doc, ctrlPressed); + export function DeselectDoc(docView: DocumentView): void { + manager.DeselectDoc(docView); + } + export function SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { + manager.SelectDoc(docView, ctrlPressed); } export function IsSelected(doc: DocumentView): boolean { diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index d120c3a0c..5238ad114 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -10,6 +10,7 @@ import { SelectionManager } from '../../util/SelectionManager'; import { ContextMenu } from '../ContextMenu'; import { FieldViewProps } from '../nodes/FieldView'; import './CollectionBaseView.scss'; +import { DocumentManager } from '../../util/DocumentManager'; export enum CollectionViewType { Invalid, @@ -129,7 +130,8 @@ export class CollectionBaseView extends React.Component { @action.bound removeDocument(doc: Doc): boolean { - SelectionManager.DeselectAll(); + 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 const value = Cast(props.Document[props.fieldKey], listSpec(Doc), []); @@ -163,7 +165,6 @@ export class CollectionBaseView extends React.Component { return true; } if (this.removeDocument(doc)) { - SelectionManager.DeselectAll(); return addDocument(doc); } return false; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index ca7c99f28..ba7e6cf9e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -44,8 +44,9 @@ export class CollectionFreeFormLinkView extends React.Component text += StrCast(l.title) + "(" + StrCast(l.linkDescription) + "), "); - text = text.substr(0, text.length - 2); + let first = this.props.LinkDocs[0]; + if (this.props.LinkDocs.length === 1) text += first.title + (first.linkDescription ? "(" + StrCast(first.linkDescription) + ")" : ""); + else text = "-multiple-"; return ( <> ; private _inputReactionDisposer: Opt; @@ -136,25 +135,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } } - @undoBatch - @action - drop = async (e: Event, de: DragManager.DropEvent) => { - if (de.data instanceof DragManager.LinkDragData) { - let sourceDoc = de.data.linkSourceDocument; - let destDoc = this.props.Document; - - DocUtils.MakeLink(sourceDoc, destDoc); - de.data.droppedDocuments.push(destDoc); - e.stopPropagation(); - } - } - componentDidMount() { - if (this._ref.current) { - this._dropDisposer = DragManager.MakeDropTarget(this._ref.current, { - handlers: { drop: this.drop.bind(this) } - }); - } const config = { schema, inpRules, //these currently don't do anything, but could eventually be helpful @@ -250,9 +231,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe if (this._proxyReactionDisposer) { this._proxyReactionDisposer(); } - if (this._dropDisposer) { - this._dropDisposer(); - } } onPointerDown = (e: React.PointerEvent): void => { -- cgit v1.2.3-70-g09d2