From b63bcb791013766d5d16e4f38964499268f904c4 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 21 Apr 2019 00:03:52 -0400 Subject: fixed a bunch of issues related to moving documents with different zoom bases. --- .../views/collections/CollectionBaseView.tsx | 78 ++++++++++------------ 1 file changed, 36 insertions(+), 42 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 0c1cd7b8f..eec01bb3f 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -8,6 +8,7 @@ import { ListField } from '../../../fields/ListField'; import { NumberField } from '../../../fields/NumberField'; import { ContextMenu } from '../ContextMenu'; import { FieldViewProps } from '../nodes/FieldView'; +import { TextField } from '../../../fields/TextField'; export enum CollectionViewType { Invalid, @@ -87,57 +88,50 @@ export class CollectionBaseView extends React.Component { @action.bound addDocument(doc: Document, allowDuplicates: boolean = false): boolean { - let props = this.props; - var curPage = props.Document.GetNumber(KeyStore.CurPage, -1); + var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1); doc.SetOnPrototype(KeyStore.Page, new NumberField(curPage)); if (curPage >= 0) { - doc.SetOnPrototype(KeyStore.AnnotationOn, props.Document); + doc.SetOnPrototype(KeyStore.AnnotationOn, this.props.Document); } - if (props.Document.Get(props.fieldKey) instanceof Field) { - //TODO This won't create the field if it doesn't already exist - const value = props.Document.GetData(props.fieldKey, ListField, new Array()); - if (!this.createsCycle(doc, props.Document)) { + if (this.props.Document.Get(this.props.fieldKey) instanceof Field) { + const value = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); + if (!this.createsCycle(doc, this.props.Document)) { if (!value.some(v => v.Id === doc.Id) || allowDuplicates) { value.push(doc); + doc.SetNumber(KeyStore.ZoomBasis, this.props.Document.GetNumber(KeyStore.Scale, 1)); } return true; } - else { - return false; - } - } else { - let proto = props.Document.GetPrototype(); - if (!proto || proto === FieldWaiting || !this.createsCycle(proto, doc)) { - const field = new ListField([doc]); - // const script = CompileScript(` - // if(added) { - // console.log("added " + field.Title + " " + doc.Title); - // } else { - // console.log("removed " + field.Title + " " + doc.Title); - // } - // `, { - // addReturn: false, - // params: { - // field: Document.name, - // added: "boolean" - // }, - // capturedVariables: { - // doc: this.props.Document - // } - // }); - // if (script.compiled) { - // field.addScript(new ScriptField(script)); - // } - props.Document.SetOnPrototype(props.fieldKey, field); - } - else { - return false; - } - } - if (true || this.isAnnotationOverlay) { - doc.SetNumber(KeyStore.Zoom, this.props.Document.GetNumber(KeyStore.Scale, 1)); } - return true; + // bcz: What is this code trying to do? + // else { + // let proto = props.Document.GetPrototype(); + // if (!proto || proto === FieldWaiting || !this.createsCycle(proto, doc)) { + // const field = new ListField([doc]); + // // const script = CompileScript(` + // // if(added) { + // // console.log("added " + field.Title + " " + doc.Title); + // // } else { + // // console.log("removed " + field.Title + " " + doc.Title); + // // } + // // `, { + // // addReturn: false, + // // params: { + // // field: Document.name, + // // added: "boolean" + // // }, + // // capturedVariables: { + // // doc: this.props.Document + // // } + // // }); + // // if (script.compiled) { + // // field.addScript(new ScriptField(script)); + // // } + // props.Document.SetOnPrototype(props.fieldKey, field); + // return true; + // } + // } + return false; } @action.bound -- cgit v1.2.3-70-g09d2 From aa3bf8c34df0030a631a945673cfdfbcd6320a15 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 22 Apr 2019 22:21:51 -0400 Subject: fixing annotations on documents --- .../views/collections/CollectionBaseView.tsx | 11 +++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 50 ++++++++++------------ .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- 3 files changed, 28 insertions(+), 35 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 eec01bb3f..540df82e7 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -93,16 +93,15 @@ export class CollectionBaseView extends React.Component { if (curPage >= 0) { doc.SetOnPrototype(KeyStore.AnnotationOn, this.props.Document); } - if (this.props.Document.Get(this.props.fieldKey) instanceof Field) { - const value = this.props.Document.GetList(this.props.fieldKey, [] as Document[]); - if (!this.createsCycle(doc, this.props.Document)) { - if (!value.some(v => v.Id === doc.Id) || allowDuplicates) { - value.push(doc); + this.props.Document.GetOrCreateAsync(this.props.fieldKey, ListField, (value: ListField) => { + if (value && !this.createsCycle(doc, this.props.Document)) { + if (!value.Data.some(v => v.Id === doc.Id) || allowDuplicates) { + value.Data.push(doc); doc.SetNumber(KeyStore.ZoomBasis, this.props.Document.GetNumber(KeyStore.Scale, 1)); } return true; } - } + }); // bcz: What is this code trying to do? // else { // let proto = props.Document.GetPrototype(); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 69a3aac67..6cc16cd79 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,5 +1,6 @@ import { action, computed, observable, trace } from "mobx"; import { observer } from "mobx-react"; +import Measure from "react-measure"; import { Document } from "../../../../fields/Document"; import { KeyStore } from "../../../../fields/KeyStore"; import { emptyFunction, returnFalse, returnOne } from "../../../../Utils"; @@ -21,7 +22,6 @@ import "./CollectionFreeFormView.scss"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); import v5 = require("uuid/v5"); -import { BooleanField } from "../../../../fields/BooleanField"; @observer export class CollectionFreeFormView extends CollectionSubView { @@ -48,7 +48,11 @@ export class CollectionFreeFormView extends CollectionSubView { this._selectOnLoaded = newBox.Id;// track the new text box so we can give it a prop that tells it to focus itself when it's displayed this.addDocument(newBox, false); } + @action private addDocument = (newBox: Document, allowDuplicates: boolean) => { + if (this.isAnnotationOverlay) { + newBox.SetNumber(KeyStore.ZoomBasis, this.props.Document.GetNumber(KeyStore.Scale, 1)); + } return this.props.addDocument(this.bringToFront(newBox), false); } private selectDocuments = (docs: Document[]) => { @@ -71,27 +75,20 @@ export class CollectionFreeFormView extends CollectionSubView { @action drop = (e: Event, de: DragManager.DropEvent) => { if (super.drop(e, de) && de.data instanceof DragManager.DocumentDragData) { + const [x, y] = this.getTransform().transformPoint(de.x - de.data.xOffset, de.y - de.data.yOffset); if (de.data.droppedDocuments.length) { - let dragDoc = de.data.droppedDocuments[0]; - let zoom = dragDoc.GetNumber(KeyStore.ZoomBasis, 1); - let [xp, yp] = this.getTransform().transformPoint(de.x, de.y); - let x = xp - de.data.xOffset / zoom; - let y = yp - de.data.yOffset / zoom; - - let dropX = dragDoc.GetNumber(KeyStore.X, 0); - let dropY = dragDoc.GetNumber(KeyStore.Y, 0); + let dropX = de.data.droppedDocuments[0].GetNumber(KeyStore.X, 0); + let dropY = de.data.droppedDocuments[0].GetNumber(KeyStore.Y, 0); de.data.droppedDocuments.map(d => { - d.SetNumber(KeyStore.X, x + (d.GetNumber(KeyStore.X, 0)) - dropX); - d.SetNumber(KeyStore.Y, y + (d.GetNumber(KeyStore.Y, 0)) - dropY); - if (!d.GetBoolean(KeyStore.IsMinimized, false)) { - if (!d.GetNumber(KeyStore.Width, 0)) { - d.SetNumber(KeyStore.Width, 300); - } - if (!d.GetNumber(KeyStore.Height, 0)) { - let nw = d.GetNumber(KeyStore.NativeWidth, 0); - let nh = d.GetNumber(KeyStore.NativeHeight, 0); - d.SetNumber(KeyStore.Height, nw && nh ? nh / nw * d.Width() : 300); - } + d.SetNumber(KeyStore.X, x + (d.GetNumber(KeyStore.X, 0) - dropX)); + d.SetNumber(KeyStore.Y, y + (d.GetNumber(KeyStore.Y, 0) - dropY)); + if (!d.GetNumber(KeyStore.Width, 0)) { + d.SetNumber(KeyStore.Width, 300); + } + if (!d.GetNumber(KeyStore.Height, 0)) { + let nw = d.GetNumber(KeyStore.NativeWidth, 0); + let nh = d.GetNumber(KeyStore.NativeHeight, 0); + d.SetNumber(KeyStore.Height, nw && nh ? nh / nw * d.Width() : 300); } this.bringToFront(d); }); @@ -114,7 +111,7 @@ export class CollectionFreeFormView extends CollectionSubView { var dv = DocumentManager.Instance.getDocumentView(doc); return childSelected || (dv && SelectionManager.IsSelected(dv) ? true : false); }, false); - if ((e.button === 0 && !e.altKey && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) && (childSelected || this.props.active())) { + if (((e.button === 2 && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) || (e.button === 0 && e.altKey)) && (childSelected || this.props.active())) { document.removeEventListener("pointermove", this.onPointerMove); document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); @@ -191,22 +188,21 @@ export class CollectionFreeFormView extends CollectionSubView { // if (modes[e.deltaMode] === 'pixels') coefficient = 50; // else if (modes[e.deltaMode] === 'lines') coefficient = 1000; // This should correspond to line-height?? let deltaScale = (1 - (e.deltaY / coefficient)); - if (deltaScale < 0) deltaScale = -deltaScale; if (deltaScale * this.zoomScaling() < 1 && this.isAnnotationOverlay) { deltaScale = 1 / this.zoomScaling(); } 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); - this.props.Document.SetNumber(KeyStore.Scale, Math.abs(safeScale)); - this.setPan(-localTransform.TranslateX / safeScale, -localTransform.TranslateY / safeScale); + this.props.Document.SetNumber(KeyStore.Scale, localTransform.Scale); + this.setPan(-localTransform.TranslateX / localTransform.Scale, -localTransform.TranslateY / localTransform.Scale); e.stopPropagation(); } } @action setPan(panX: number, panY: number) { + MainOverlayTextBox.Instance.SetTextDoc(); var scale = this.getLocalTransform().inverse().Scale; const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX)); const newPanY = Math.min((1 - 1 / scale) * this.nativeHeight, Math.max(0, panY)); @@ -265,9 +261,7 @@ export class CollectionFreeFormView extends CollectionSubView { let docviews = this.props.Document.GetList(this.props.fieldKey, [] as Document[]).filter(doc => doc).reduce((prev, doc) => { var page = doc.GetNumber(KeyStore.Page, -1); if (page === curPage || page === -1) { - let minim = doc.GetT(KeyStore.IsMinimized, BooleanField); - if (minim === undefined || (minim && !minim.Data)) - prev.push(); + prev.push(); } return prev; }, [] as JSX.Element[]); diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 12e5bdf1f..9fa6a4f51 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -72,7 +72,7 @@ export class CollectionFreeFormDocumentView extends React.Component Date: Mon, 22 Apr 2019 22:29:31 -0400 Subject: from last --- src/client/views/collections/CollectionBaseView.tsx | 1 + 1 file changed, 1 insertion(+) (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 540df82e7..b19f01350 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -102,6 +102,7 @@ export class CollectionBaseView extends React.Component { return true; } }); + return true; // bcz: What is this code trying to do? // else { // let proto = props.Document.GetPrototype(); -- cgit v1.2.3-70-g09d2 From 448a62581fbbad3af8073a195ca45aba2270d239 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 23 Apr 2019 01:14:45 -0400 Subject: right btn option for mac and windows. --- src/client/views/MainOverlayTextBox.tsx | 2 +- src/client/views/collections/CollectionBaseView.tsx | 12 +++++++----- .../collectionFreeForm/CollectionFreeFormView.tsx | 11 ++++++----- .../views/collections/collectionFreeForm/MarqueeView.tsx | 12 +++++++----- src/client/views/nodes/DocumentView.tsx | 3 ++- 5 files changed, 23 insertions(+), 17 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index 2b72b09c6..9aaaad084 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -71,7 +71,7 @@ export class MainOverlayTextBox extends React.Component document.removeEventListener("pointermove", this.textBoxMove); document.removeEventListener('pointerup', this.textBoxUp); let dragData = new DragManager.DocumentDragData([this.TextDoc!]); - const [left, top] = this._textXf.inverse().transformPoint(0, 0); + const [left, top] = this._textXf().inverse().transformPoint(0, 0); dragData.xOffset = e.clientX - left; dragData.yOffset = e.clientY - top; DragManager.StartDocumentDrag([this._textTargetDiv!], dragData, e.clientX, e.clientY, { diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index b19f01350..9ae2993be 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -93,15 +93,17 @@ export class CollectionBaseView extends React.Component { if (curPage >= 0) { doc.SetOnPrototype(KeyStore.AnnotationOn, this.props.Document); } - this.props.Document.GetOrCreateAsync(this.props.fieldKey, ListField, (value: ListField) => { - if (value && !this.createsCycle(doc, this.props.Document)) { + if (!this.createsCycle(doc, this.props.Document)) { + doc.SetNumber(KeyStore.ZoomBasis, this.props.Document.GetNumber(KeyStore.Scale, 1)); + let value = this.props.Document.Get(this.props.fieldKey) as ListField; + if (value) { if (!value.Data.some(v => v.Id === doc.Id) || allowDuplicates) { value.Data.push(doc); - doc.SetNumber(KeyStore.ZoomBasis, this.props.Document.GetNumber(KeyStore.Scale, 1)); } - return true; + } else { + this.props.Document.Set(this.props.fieldKey, new ListField([doc])); } - }); + } return true; // bcz: What is this code trying to do? // else { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 4144219ad..117343ef3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -20,11 +20,11 @@ import "./CollectionFreeFormView.scss"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); import v5 = require("uuid/v5"); -import { MainOverlayTextBox } from "../../MainOverlayTextBox"; import { BooleanField } from "../../../../fields/BooleanField"; @observer export class CollectionFreeFormView extends CollectionSubView { + 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; @@ -113,9 +113,11 @@ export class CollectionFreeFormView extends CollectionSubView { var dv = DocumentManager.Instance.getDocumentView(doc); return childSelected || (dv && SelectionManager.IsSelected(dv) ? true : false); }, false); - // if ((e.button === 0 && !e.altKey && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) && (childSelected || this.props.active())) { - - if (((e.button === 2 && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) || (e.button === 0 && e.altKey)) && (childSelected || this.props.active())) { + if ((CollectionFreeFormView.RIGHT_BTN_DRAG && + (((e.button === 2 && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) || + (e.button === 0 && e.altKey)) && (childSelected || this.props.active()))) || + (!CollectionFreeFormView.RIGHT_BTN_DRAG && + ((e.button === 0 && !e.altKey && (!this.isAnnotationOverlay || this.zoomScaling() !== 1)) && (childSelected || this.props.active())))) { document.removeEventListener("pointermove", this.onPointerMove); document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); @@ -295,7 +297,6 @@ export class CollectionFreeFormView extends CollectionSubView { getContainerTransform={this.getContainerTransform} getTransform={this.getTransform}> - {this.childViews} diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 3adcb11bd..8455323fd 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -70,7 +70,8 @@ export class MarqueeView extends React.Component } @action onPointerDown = (e: React.PointerEvent): void => { - if (e.buttons === 1 && !e.altKey && !e.metaKey && this.props.container.props.active()) { + if ((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())) { this._downX = this._lastX = e.pageX; this._downY = this._lastY = e.pageY; this._used = false; @@ -79,8 +80,6 @@ export class MarqueeView extends React.Component document.addEventListener("pointermove", this.onPointerMove, true); document.addEventListener("pointerup", this.onPointerUp, true); document.addEventListener("keydown", this.marqueeCommand, true); - if (e.button == 2 || e.altKey) - e.stopPropagation(); } if (e.altKey) e.preventDefault(); @@ -95,7 +94,9 @@ export class MarqueeView extends React.Component this._showOnUp = false; PreviewCursor.Visible = false; } - if (!this._used && e.buttons === 1 && !e.metaKey && + if (!this._used && + (!CollectionFreeFormView.RIGHT_BTN_DRAG && (e.buttons === 2 || (e.buttons == 1 && e.altKey))) || + (CollectionFreeFormView.RIGHT_BTN_DRAG && e.buttons === 1 && !e.altKey && !e.metaKey) && (Math.abs(this._lastX - this._downX) > MarqueeView.DRAG_THRESHOLD || Math.abs(this._lastY - this._downY) > MarqueeView.DRAG_THRESHOLD)) { this._visible = true; e.stopPropagation(); @@ -113,7 +114,8 @@ export class MarqueeView extends React.Component if (this._showOnUp) { PreviewCursor.Show(this.hideCursor, this._downX, this._downY); document.addEventListener("keypress", this.onKeyPress, false); - } else if (e.button === 0) { + } else if ((CollectionFreeFormView.RIGHT_BTN_DRAG && e.button === 0 && !e.altKey && !e.metaKey) || + (!CollectionFreeFormView.RIGHT_BTN_DRAG && ((e.button === 0 && e.altKey) || e.button === 2))) { let mselect = this.marqueeSelect(); if (!e.shiftKey) { SelectionManager.DeselectAll(mselect.length ? undefined : this.props.container.props.Document); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index c82b86ea9..2f8ac9f20 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -23,6 +23,7 @@ import { ContextMenu } from "../ContextMenu"; import { DocumentContentsView } from "./DocumentContentsView"; import "./DocumentView.scss"; import React = require("react"); +import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; export interface DocumentViewProps { ContainingCollectionView: Opt; @@ -98,7 +99,7 @@ export class DocumentView extends React.Component { onPointerDown = (e: React.PointerEvent): void => { this._downX = e.clientX; this._downY = e.clientY; - if (e.button === 2 && !this.isSelected()) { + if (CollectionFreeFormView.RIGHT_BTN_DRAG && (e.button === 2 || (e.button === 0 && e.altKey)) && !this.isSelected()) { return; } if (e.shiftKey && e.buttons === 2) { -- cgit v1.2.3-70-g09d2 From 49131cc84b0f3e739edb5ffcd64f3acc9469f658 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 23 Apr 2019 12:17:12 -0400 Subject: fixes to zoom scaling, moved and fixed icon stuff into CollectionFreeFormDocumentView. several smaller bugs. --- src/client/views/DocumentDecorations.tsx | 41 ++++- src/client/views/Main.tsx | 1 + .../views/collections/CollectionBaseView.tsx | 4 +- .../views/collections/CollectionDockingView.tsx | 1 + .../views/collections/CollectionSchemaView.tsx | 3 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 1 + .../views/nodes/CollectionFreeFormDocumentView.tsx | 174 +++++++++++++++----- src/client/views/nodes/DocumentView.tsx | 180 +++++---------------- src/client/views/nodes/ImageBox.tsx | 5 +- 9 files changed, 215 insertions(+), 195 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index d704b6c47..95910c7be 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -18,6 +18,7 @@ import React = require("react"); import { CompileScript } from "../util/Scripting"; import { IconBox } from "./nodes/IconBox"; import { FieldValue, Field } from "../../fields/Field"; +import { Documents } from "../documents/Documents"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -134,11 +135,12 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> @action onBackgroundMove = (e: PointerEvent): void => { let dragDocView = SelectionManager.SelectedDocuments()[0]; - const [left, top] = dragDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); + const [left, top] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).inverse().transformPoint(0, 0); let dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); + const [xoff, yoff] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).transformDirection(e.x - left, e.y - top); + dragData.xOffset = xoff; + dragData.yOffset = yoff; dragData.aliasOnDrop = false; - dragData.xOffset = e.x - left; - dragData.yOffset = e.y - top; let move = SelectionManager.SelectedDocuments()[0].props.moveDocument; dragData.moveDocument = move; this.Interacting = this._dragging = true; @@ -213,12 +215,39 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> this._minimizedX = snapped ? selDocPos[0] + 4 : e.clientX; this._minimizedY = snapped ? selDocPos[1] - 18 : e.clientY; let selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd); - Promise.all(selectedDocs.map(async selDoc => await selDoc.getIconDoc())).then(minDocSet => + Promise.all(selectedDocs.map(async selDoc => await this.getIconDoc(selDoc))).then(minDocSet => this.moveIconDocs(SelectionManager.SelectedDocuments()) ); this._iconifying = snapped; } } + + + @action createIcon = (docView: DocumentView, layoutString: string): Document => { + let doc = docView.props.Document; + let iconDoc = Documents.IconDocument(layoutString); + iconDoc.SetText(KeyStore.Title, "ICON" + doc.Title) + iconDoc.SetBoolean(KeyStore.IsMinimized, false); + iconDoc.SetNumber(KeyStore.NativeWidth, 0); + iconDoc.SetNumber(KeyStore.NativeHeight, 0); + iconDoc.SetNumber(KeyStore.X, doc.GetNumber(KeyStore.X, 0)); + iconDoc.SetNumber(KeyStore.Y, doc.GetNumber(KeyStore.Y, 0) - 24); + iconDoc.Set(KeyStore.Prototype, doc); + iconDoc.Set(KeyStore.MaximizedDoc, doc); + doc.Set(KeyStore.MinimizedDoc, iconDoc); + docView.props.addDocument && docView.props.addDocument(iconDoc, false); + return iconDoc; + } + @action + public getIconDoc = async (docView: DocumentView): Promise => { + let doc = docView.props.Document; + return await doc.GetTAsync(KeyStore.MinimizedDoc, Document).then(async mindoc => + mindoc ? mindoc : + await doc.GetTAsync(KeyStore.BackgroundLayout, TextField).then(async field => + (field instanceof TextField) ? this.createIcon(docView, field.Data) : + await doc.GetTAsync(KeyStore.Layout, TextField).then(field => + (field instanceof TextField) ? this.createIcon(docView, field.Data) : undefined))); + } @action onMinimizeUp = (e: PointerEvent): void => { e.stopPropagation(); @@ -226,7 +255,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> document.removeEventListener("pointermove", this.onMinimizeMove); document.removeEventListener("pointerup", this.onMinimizeUp); let selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd); - Promise.all(selectedDocs.map(async selDoc => await selDoc.getIconDoc())).then(minDocSet => { + Promise.all(selectedDocs.map(async selDoc => await this.getIconDoc(selDoc))).then(minDocSet => { let minDocs = minDocSet.filter(minDoc => minDoc instanceof Document).map(minDoc => minDoc as Document); minDocs.map(minDoc => { minDoc.SetNumber(KeyStore.X, minDocs[0].GetNumber(KeyStore.X, 0)); @@ -238,7 +267,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } }); runInAction(() => this._minimizedX = this._minimizedY = 0); - if (!this._iconifying) selectedDocs[0].toggleIcon(); + if (!this._iconifying) selectedDocs[0].props.toggleMinimized(); this._iconifying = false; }); } diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 09ef30f6b..934616aca 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -187,6 +187,7 @@ export class Main extends React.Component {
{!mainCont ? (null) : { doc.SetOnPrototype(KeyStore.AnnotationOn, this.props.Document); } if (!this.createsCycle(doc, this.props.Document)) { - doc.SetNumber(KeyStore.ZoomBasis, this.props.Document.GetNumber(KeyStore.Scale, 1)); let value = this.props.Document.Get(this.props.fieldKey) as ListField; if (value) { if (!value.Data.some(v => v.Id === doc.Id) || allowDuplicates) { @@ -103,6 +102,9 @@ export class CollectionBaseView extends React.Component { } else { this.props.Document.Set(this.props.fieldKey, new ListField([doc])); } + // set the ZoomBasis only if hasn't already been set -- bcz: maybe set/resetting the ZoomBasis should be a parameter to addDocument? + doc.GetTAsync(KeyStore.ZoomBasis, NumberField, field => !field && + doc.SetNumber(KeyStore.ZoomBasis, this.props.Document.GetNumber(KeyStore.Scale, 1))); } return true; // bcz: What is this code trying to do? diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index e4c647635..1ea18ed42 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -350,6 +350,7 @@ export class DockedFrameRenderer extends React.Component {
{ let props: FieldViewProps = { @@ -266,6 +266,7 @@ export class CollectionSchemaView extends CollectionSubView {
{ private _mainCont = React.createRef(); + private _downX: number = 0; + private _downY: number = 0; - @computed - get transform(): string { + @computed get transform() { return `scale(${this.props.ContentScaling()}, ${this.props.ContentScaling()}) translate(${this.X}px, ${this.Y}px) scale(${this.zoom}, ${this.zoom}) `; } - - @computed get zoom(): number { return 1 / this.props.Document.GetNumber(KeyStore.ZoomBasis, 1); } - @computed get zIndex(): number { return this.props.Document.GetNumber(KeyStore.ZIndex, 0); } - @computed get width(): number { return this.props.Document.Width(); } - @computed get height(): number { return this.props.Document.Height(); } - @computed get nativeWidth(): number { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); } - @computed get nativeHeight(): number { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); } - + @computed get X() { return this.props.Document.GetNumber(KeyStore.X, 0); } + @computed get Y() { return this.props.Document.GetNumber(KeyStore.Y, 0); } + @computed get zoom() { return 1 / this.props.Document.GetNumber(KeyStore.ZoomBasis, 1); } + @computed get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); } + @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); } + @computed get width() { return this.props.Document.Width(); } + @computed get height() { return this.props.Document.Height(); } + @computed get zIndex() { return this.props.Document.GetNumber(KeyStore.ZIndex, 0); } set width(w: number) { this.props.Document.SetData(KeyStore.Width, w, NumberField); if (this.nativeWidth && this.nativeHeight) { this.props.Document.SetNumber(KeyStore.Height, this.nativeHeight / this.nativeWidth * w); } } - set height(h: number) { this.props.Document.SetData(KeyStore.Height, h, NumberField); if (this.nativeWidth && this.nativeHeight) { this.props.Document.SetNumber(KeyStore.Width, this.nativeWidth / this.nativeHeight * h); } } - set zIndex(h: number) { this.props.Document.SetData(KeyStore.ZIndex, h, NumberField); } - get X() { - return this.props.Document.GetNumber(KeyStore.X, 0); - } - get Y() { - return this.props.Document.GetNumber(KeyStore.Y, 0); - } - getTransform = (): Transform => - this.props.ScreenToLocalTransform() - .translate(-this.X, -this.Y) - .scale(1 / this.contentScaling()).scale(1 / this.zoom) - contentScaling = () => (this.nativeWidth > 0 ? this.width / this.nativeWidth : 1); panelWidth = () => this.props.PanelWidth(); panelHeight = () => this.props.PanelHeight(); + toggleMinimized = () => this.toggleIcon(); + getTransform = (): Transform => this.props.ScreenToLocalTransform() + .translate(-this.X, -this.Y) + .scale(1 / this.contentScaling()).scale(1 / this.zoom) @computed get docView() { return ; } + animateBetweenIcon(first: boolean, icon: number[], targ: number[], width: number, height: number, stime: number, target: Document, maximizing: boolean) { + setTimeout(() => { + let now = Date.now(); + let progress = Math.min(1, (now - stime) / 200); + let pval = maximizing ? + [icon[0] + (targ[0] - icon[0]) * progress, icon[1] + (targ[1] - icon[1]) * progress] : + [targ[0] + (icon[0] - targ[0]) * progress, targ[1] + (icon[1] - targ[1]) * progress]; + target.SetNumber(KeyStore.Width, maximizing ? 25 + (width - 25) * progress : width + (25 - width) * progress); + target.SetNumber(KeyStore.Height, maximizing ? 25 + (height - 25) * progress : height + (25 - height) * progress); + target.SetNumber(KeyStore.X, pval[0]); + target.SetNumber(KeyStore.Y, pval[1]); + if (first) { + target.SetBoolean(KeyStore.IsMinimized, false); + } + if (now < stime + 200) { + this.animateBetweenIcon(false, icon, targ, width, height, stime, target, maximizing); + } + else { + if (!maximizing) { + target.SetBoolean(KeyStore.IsMinimized, true); + target.SetNumber(KeyStore.X, targ[0]); + target.SetNumber(KeyStore.Y, targ[1]); + target.SetNumber(KeyStore.Width, width); + target.SetNumber(KeyStore.Height, height); + } + (target as any).isIconAnimating = false; + } + }, + 2); + } + @action + public toggleIcon = async (): Promise => { + SelectionManager.DeselectAll(); + let isMinimized: boolean | undefined; + let minDoc = await this.props.Document.GetTAsync(KeyStore.MinimizedDoc, Document); + if (!minDoc) return; + let minimizedDocSet = await minDoc.GetTAsync(KeyStore.LinkTags, ListField); + if (!minimizedDocSet) return; + minimizedDocSet.Data.map(async minimizedDoc => { + if (minimizedDoc instanceof Document) { + this.props.addDocument && this.props.addDocument(minimizedDoc, false); + let maximizedDoc = await minimizedDoc.GetTAsync(KeyStore.MaximizedDoc, Document); + if (maximizedDoc instanceof Document && !(maximizedDoc as any).isIconAnimating) { + (maximizedDoc as any).isIconAnimating = true; + if (isMinimized === undefined) { + let maximizedDocMinimizedState = await maximizedDoc.GetTAsync(KeyStore.IsMinimized, BooleanField); + isMinimized = (maximizedDocMinimizedState && maximizedDocMinimizedState.Data) ? true : false; + } + let minx = await minimizedDoc.GetTAsync(KeyStore.X, NumberField); + let miny = await minimizedDoc.GetTAsync(KeyStore.Y, NumberField); + let maxx = await maximizedDoc.GetTAsync(KeyStore.X, NumberField); + let maxy = await maximizedDoc.GetTAsync(KeyStore.Y, NumberField); + let maxw = await maximizedDoc.GetTAsync(KeyStore.Width, NumberField); + let maxh = await maximizedDoc.GetTAsync(KeyStore.Height, NumberField); + if (minx !== undefined && miny !== undefined && maxx !== undefined && maxy !== undefined && + maxw !== undefined && maxh !== undefined) + this.animateBetweenIcon( + true, + [minx.Data, miny.Data], [maxx.Data, maxy.Data], maxw.Data, maxh.Data, + Date.now(), maximizedDoc, isMinimized); + } + + } + }) + } + onPointerDown = (e: React.PointerEvent): void => { + e.stopPropagation(); + this._downX = e.clientX; + this._downY = e.clientY; + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointerup", this.onPointerUp); + } + onPointerUp = (e: PointerEvent): void => { + document.removeEventListener("pointerup", this.onPointerUp); + e.stopPropagation(); + if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) { + this.props.Document.GetTAsync(KeyStore.MaximizedDoc, Document).then(maxdoc => { + if (maxdoc instanceof Document) { // bcz: need a better way to associate behaviors with click events on widget-documents + SelectionManager.DeselectAll(); + this.props.addDocument && this.props.addDocument(maxdoc, false); + this.toggleIcon(); + } + }); + } + } + render() { + let maximizedDoc = this.props.Document.GetT(KeyStore.MaximizedDoc, Document); let zoomFade = 1; //var zoom = doc.GetNumber(KeyStore.ZoomBasis, 1); - // let transform = this.getTransform().scale(this.contentScaling()).inverse(); - // var [sptX, sptY] = transform.transformPoint(0, 0); - // let [bptX, bptY] = transform.transformPoint(this.props.PanelWidth(), this.props.PanelHeight()); - // let w = bptX - sptX; - // //zoomFade = area < 100 || area > 800 ? Math.max(0, Math.min(1, 2 - 5 * (zoom < this.scale ? this.scale / zoom : zoom / this.scale))) : 1; - // let fadeUp = .75 * 1800; - // let fadeDown = .075 * 1800; - // zoomFade = w < fadeDown /* || w > fadeUp */ ? Math.max(0, Math.min(1, 2 - (w < fadeDown ? fadeDown / w : w / fadeUp))) : 1; + let transform = this.getTransform().scale(this.contentScaling()).inverse(); + var [sptX, sptY] = transform.transformPoint(0, 0); + let [bptX, bptY] = transform.transformPoint(this.props.PanelWidth(), this.props.PanelHeight()); + let w = bptX - sptX; + //zoomFade = area < 100 || area > 800 ? Math.max(0, Math.min(1, 2 - 5 * (zoom < this.scale ? this.scale / zoom : zoom / this.scale))) : 1; + const screenWidth = 1800; + let fadeUp = .75 * screenWidth; + let fadeDown = (maximizedDoc ? .0075 : .075) * screenWidth; + zoomFade = w < fadeDown /* || w > fadeUp */ ? Math.max(0, Math.min(1, 2 - (w < fadeDown ? fadeDown / w : w / fadeUp))) : 1; return ( -
+
{this.docView}
); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 2f8ac9f20..8922e4b81 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -5,8 +5,6 @@ import { Field, Opt } from "../../../fields/Field"; import { Key } from "../../../fields/Key"; import { KeyStore } from "../../../fields/KeyStore"; import { ListField } from "../../../fields/ListField"; -import { NumberField } from "../../../fields/NumberField"; -import { TextField } from "../../../fields/TextField"; import { ServerUtils } from "../../../server/ServerUtil"; import { emptyFunction, Utils } from "../../../Utils"; import { Documents } from "../../documents/Documents"; @@ -40,6 +38,7 @@ export interface DocumentViewProps { selectOnLoad: boolean; parentActive: () => boolean; whenActiveChanged: (isActive: boolean) => void; + toggleMinimized: () => void; } export interface JsxArgs extends DocumentViewProps { Keys: { [name: string]: Key }; @@ -83,7 +82,6 @@ export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs { @observer export class DocumentView extends React.Component { - static _incompleteAnimations: Map = new Map(); private _downX: number = 0; private _downY: number = 0; private _mainCont = React.createRef(); @@ -96,42 +94,16 @@ export class DocumentView extends React.Component { @computed get layoutKeys(): Key[] { return this.props.Document.GetData(KeyStore.LayoutKeys, ListField, new Array()); } @computed get layoutFields(): Key[] { return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array()); } - 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; - } - if (e.shiftKey && e.buttons === 2) { - if (this.props.isTopMost) { - this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey); - } else { - CollectionDockingView.Instance.StartOtherDrag([this.props.Document], e); - } - e.stopPropagation(); - } else { - let maxdoc = this.props.Document.GetT(KeyStore.MaximizedDoc, Document); - if (this.active || - maxdoc instanceof Document // bcz: need a better way of allowing a document to handle pointer events when its not active (ie. be a top-level widget) - ) { - e.stopPropagation(); - document.removeEventListener("pointermove", this.onPointerMove); - document.addEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); - document.addEventListener("pointerup", this.onPointerUp); - } - } - } - + @action componentDidMount() { if (this._mainCont.current) { this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, { handlers: { drop: this.drop.bind(this) } }); } - runInAction(() => DocumentManager.Instance.DocumentViews.push(this)); + DocumentManager.Instance.DocumentViews.push(this); } - + @action componentDidUpdate() { if (this._dropDisposer) { this._dropDisposer(); @@ -142,12 +114,16 @@ export class DocumentView extends React.Component { }); } } - + @action componentWillUnmount() { if (this._dropDisposer) { this._dropDisposer(); } - runInAction(() => DocumentManager.Instance.DocumentViews.splice(DocumentManager.Instance.DocumentViews.indexOf(this), 1)); + DocumentManager.Instance.DocumentViews.splice(DocumentManager.Instance.DocumentViews.indexOf(this), 1); + } + + stopPropagation = (e: React.SyntheticEvent) => { + e.stopPropagation(); } startDragging(x: number, y: number, dropAliasOfDraggedDoc: boolean) { @@ -168,43 +144,51 @@ export class DocumentView extends React.Component { } } - onPointerMove = (e: PointerEvent): void => { - if (e.cancelBubble) { + 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; } - if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { + if (e.shiftKey && e.buttons === 2) { + if (this.props.isTopMost) { + this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey); + } else { + CollectionDockingView.Instance.StartOtherDrag([this.props.Document], e); + } + e.stopPropagation(); + } else if (this.active) { document.removeEventListener("pointermove", this.onPointerMove); + document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); - if (!e.altKey && (!this.topMost || e.buttons === 2)) { - this.startDragging(this._downX, this._downY, e.ctrlKey || e.altKey); + document.addEventListener("pointerup", this.onPointerUp); + } + } + onPointerMove = (e: PointerEvent): void => { + if (!e.cancelBubble) { + 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 || e.buttons === 2)) { + this.startDragging(this._downX, this._downY, e.ctrlKey || e.altKey); + } } + e.stopPropagation(); + e.preventDefault(); } - e.stopPropagation(); - e.preventDefault(); } onPointerUp = (e: PointerEvent): void => { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); - e.stopPropagation(); if (!SelectionManager.IsSelected(this) && e.button !== 2 && Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) { - this.props.Document.GetTAsync(KeyStore.MaximizedDoc, Document).then(maxdoc => { - if (maxdoc instanceof Document) { // bcz: need a better way to associate behaviors with click events on widget-documents - this.props.addDocument && this.props.addDocument(maxdoc, false); - this.toggleIcon(); - } else - SelectionManager.SelectDoc(this, e.ctrlKey); - }); + SelectionManager.SelectDoc(this, e.ctrlKey); } } - stopPropagation = (e: React.SyntheticEvent) => { - e.stopPropagation(); - } deleteClicked = (): void => { this.props.removeDocument && this.props.removeDocument(this.props.Document); } - fieldsClicked = (e: React.MouseEvent): void => { let kvp = Documents.KVPDocument(this.props.Document, { width: 300, height: 300 }); CollectionDockingView.Instance.AddRightSplit(kvp); @@ -215,7 +199,6 @@ export class DocumentView extends React.Component { ContextMenu.Instance.addItem({ description: "Close Full Screen", event: this.closeFullScreenClicked }); ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15); } - closeFullScreenClicked = (e: React.MouseEvent): void => { CollectionDockingView.Instance.CloseFullScreen(); ContextMenu.Instance.clearItems(); @@ -223,92 +206,6 @@ export class DocumentView extends React.Component { ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15); } - @action createIcon = (layoutString: string): Document => { - let iconDoc = Documents.IconDocument(layoutString); - iconDoc.SetText(KeyStore.Title, "ICON" + this.props.Document.Title) - iconDoc.SetBoolean(KeyStore.IsMinimized, false); - iconDoc.SetNumber(KeyStore.NativeWidth, 0); - iconDoc.SetNumber(KeyStore.NativeHeight, 0); - iconDoc.SetNumber(KeyStore.X, this.props.Document.GetNumber(KeyStore.X, 0)); - iconDoc.SetNumber(KeyStore.Y, this.props.Document.GetNumber(KeyStore.Y, 0) - 24); - iconDoc.Set(KeyStore.Prototype, this.props.Document); - iconDoc.Set(KeyStore.MaximizedDoc, this.props.Document); - this.props.Document.Set(KeyStore.MinimizedDoc, iconDoc); - this.props.addDocument && this.props.addDocument(iconDoc, false); - return iconDoc; - } - - animateBetweenIcon(icon: number[], targ: number[], width: number, height: number, stime: number, target: Document, maximizing: boolean) { - setTimeout(() => { - let now = Date.now(); - let progress = Math.min(1, (now - stime) / 200); - let pval = maximizing ? - [icon[0] + (targ[0] - icon[0]) * progress, icon[1] + (targ[1] - icon[1]) * progress] : - [targ[0] + (icon[0] - targ[0]) * progress, targ[1] + (icon[1] - targ[1]) * progress]; - target.SetNumber(KeyStore.Width, maximizing ? 25 + (width - 25) * progress : width + (25 - width) * progress); - target.SetNumber(KeyStore.Height, maximizing ? 25 + (height - 25) * progress : height + (25 - height) * progress); - target.SetNumber(KeyStore.X, pval[0]); - target.SetNumber(KeyStore.Y, pval[1]); - if (now < stime + 200) { - this.animateBetweenIcon(icon, targ, width, height, stime, target, maximizing); - } - else { - if (!maximizing) { - target.SetBoolean(KeyStore.IsMinimized, true); - target.SetNumber(KeyStore.X, targ[0]); - target.SetNumber(KeyStore.Y, targ[1]); - target.SetNumber(KeyStore.Width, width); - target.SetNumber(KeyStore.Height, height); - } - DocumentView._incompleteAnimations.set(target.Id, false); - } - }, - 2); - } - - @action - public toggleIcon = async (): Promise => { - SelectionManager.DeselectAll(); - let isMinimized: boolean | undefined; - let minDoc = await this.props.Document.GetTAsync(KeyStore.MinimizedDoc, Document); - if (!minDoc) return; - let minimizedDocSet = await minDoc.GetTAsync(KeyStore.LinkTags, ListField); - if (!minimizedDocSet) return; - minimizedDocSet.Data.map(async minimizedDoc => { - if (minimizedDoc instanceof Document) { - this.props.addDocument && this.props.addDocument(minimizedDoc, false); - let maximizedDoc = await minimizedDoc.GetTAsync(KeyStore.MaximizedDoc, Document); - if (maximizedDoc instanceof Document && !DocumentView._incompleteAnimations.get(maximizedDoc.Id)) { - DocumentView._incompleteAnimations.set(maximizedDoc.Id, true); - isMinimized = isMinimized === undefined ? maximizedDoc.GetBoolean(KeyStore.IsMinimized, false) : isMinimized; - maximizedDoc.SetBoolean(KeyStore.IsMinimized, false); - let minx = await minimizedDoc.GetTAsync(KeyStore.X, NumberField); - let miny = await minimizedDoc.GetTAsync(KeyStore.Y, NumberField); - let maxx = await maximizedDoc.GetTAsync(KeyStore.X, NumberField); - let maxy = await maximizedDoc.GetTAsync(KeyStore.Y, NumberField); - let maxw = await maximizedDoc.GetTAsync(KeyStore.Width, NumberField); - let maxh = await maximizedDoc.GetTAsync(KeyStore.Height, NumberField); - if (minx !== undefined && miny !== undefined && maxx !== undefined && maxy !== undefined && - maxw !== undefined && maxh !== undefined) - this.animateBetweenIcon( - [minx.Data, miny.Data], [maxx.Data, maxy.Data], maxw.Data, maxh.Data, - Date.now(), maximizedDoc, isMinimized); - } - - } - }) - } - - @action - public getIconDoc = async (): Promise => { - return await this.props.Document.GetTAsync(KeyStore.MinimizedDoc, Document).then(async mindoc => - mindoc ? mindoc : - await this.props.Document.GetTAsync(KeyStore.BackgroundLayout, TextField).then(async field => - (field instanceof TextField) ? this.createIcon(field.Data) : - await this.props.Document.GetTAsync(KeyStore.Layout, TextField).then(field => - (field instanceof TextField) ? this.createIcon(field.Data) : undefined))); - } - @undoBatch @action drop = (e: Event, de: DragManager.DropEvent) => { @@ -353,6 +250,7 @@ export class DocumentView extends React.Component { } } + @action onDrop = (e: React.DragEvent) => { let text = e.dataTransfer.getData("text/plain"); if (!e.isDefaultPrevented() && text && text.startsWith(" { isSelected = () => SelectionManager.IsSelected(this); select = (ctrlPressed: boolean) => SelectionManager.SelectDoc(this, ctrlPressed); - @computed get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); } @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); } @computed get contents() { return (); } - render() { var scaling = this.props.ContentScaling(); var nativeHeight = this.nativeHeight > 0 ? this.nativeHeight.toString() + "px" : "100%"; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 5d9aefd61..a16fd5007 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -16,7 +16,7 @@ import { FieldView, FieldViewProps } from './FieldView'; import "./ImageBox.scss"; import React = require("react"); import { InkingControl } from '../InkingControl'; -import { InkTool } from '../../../fields/InkField'; +import { NumberField } from '../../../fields/NumberField'; @observer export class ImageBox extends React.Component { @@ -42,7 +42,8 @@ export class ImageBox extends React.Component { var w = this._imgRef.current!.naturalWidth; if (this._photoIndex === 0) { this.props.Document.SetNumber(KeyStore.NativeHeight, this.props.Document.GetNumber(KeyStore.NativeWidth, 0) * h / w); - this.props.Document.SetNumber(KeyStore.Height, this.props.Document.Width() * h / w); + this.props.Document.GetTAsync(KeyStore.Width, NumberField, field => + field && this.props.Document.SetNumber(KeyStore.Height, field.Data * h / w)); } } -- cgit v1.2.3-70-g09d2 From 1eaf7210492e3cc968f26d848c6db7b4e603a657 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 23 Apr 2019 15:24:10 -0400 Subject: maybe working events? --- src/client/util/SelectionManager.ts | 6 ++---- src/client/views/collections/CollectionBaseView.tsx | 7 +++++-- .../views/collections/collectionFreeForm/MarqueeView.tsx | 16 +++++++++++----- .../views/nodes/CollectionFreeFormDocumentView.tsx | 1 - src/client/views/nodes/DocumentView.tsx | 14 +++++++++----- src/client/views/nodes/FormattedTextBox.tsx | 7 ++++++- 6 files changed, 33 insertions(+), 18 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 92d78696e..0e7b374e9 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -1,9 +1,7 @@ -import { observable, action } from "mobx"; -import { DocumentView } from "../views/nodes/DocumentView"; +import { action, observable } from "mobx"; import { Document } from "../../fields/Document"; -import { Main } from "../views/Main"; import { MainOverlayTextBox } from "../views/MainOverlayTextBox"; -import { DragManager } from "./DragManager"; +import { DocumentView } from "../views/nodes/DocumentView"; export namespace SelectionManager { class Manager { diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 962cb9b65..097236c1d 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -103,8 +103,11 @@ export class CollectionBaseView extends React.Component { this.props.Document.Set(this.props.fieldKey, new ListField([doc])); } // set the ZoomBasis only if hasn't already been set -- bcz: maybe set/resetting the ZoomBasis should be a parameter to addDocument? - doc.GetTAsync(KeyStore.ZoomBasis, NumberField, field => !field && - doc.SetNumber(KeyStore.ZoomBasis, this.props.Document.GetNumber(KeyStore.Scale, 1))); + if (this.collectionViewType === CollectionViewType.Freeform || this.collectionViewType === CollectionViewType.Invalid) { + let zoom = this.props.Document.GetNumber(KeyStore.Scale, 1); + let screen = this.props.ScreenToLocalTransform().inverse().Scale / (this.props as any).ContentScaling() * zoom; + doc.SetNumber(KeyStore.ZoomBasis, screen); + } } return true; // bcz: What is this code trying to do? diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index a624c671f..48844f10c 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -79,6 +79,7 @@ export class MarqueeView extends React.Component document.addEventListener("pointermove", this.onPointerMove, true); document.addEventListener("pointerup", this.onPointerUp, true); document.addEventListener("keydown", this.marqueeCommand, true); + e.stopPropagation(); } if (e.altKey) e.preventDefault(); @@ -110,10 +111,7 @@ export class MarqueeView extends React.Component onPointerUp = (e: PointerEvent): void => { this.cleanupInteractions(true); this._visible = false; - if (this._showOnUp) { - PreviewCursor.Show(this.hideCursor, this._downX, this._downY); - document.addEventListener("keypress", this.onKeyPress, false); - } else if ((CollectionFreeFormView.RIGHT_BTN_DRAG && e.button === 0 && !e.altKey && !e.metaKey) || + if (!this._showOnUp && (CollectionFreeFormView.RIGHT_BTN_DRAG && e.button === 0 && !e.altKey && !e.metaKey) || (!CollectionFreeFormView.RIGHT_BTN_DRAG && ((e.button === 0 && e.altKey) || e.button === 2))) { let mselect = this.marqueeSelect(); if (!e.shiftKey) { @@ -125,6 +123,12 @@ export class MarqueeView extends React.Component e.preventDefault(); } + @action + onClick = (e: MouseEvent): void => { + PreviewCursor.Show(this.hideCursor, this._downX, this._downY); + document.addEventListener("keypress", this.onKeyPress, false); + } + intersectRect(r1: { left: number, top: number, width: number, height: number }, r2: { left: number, top: number, width: number, height: number }) { return !(r2.left > r1.left + r1.width || r2.left + r2.width < r1.left || r2.top > r1.top + r1.height || r2.top + r2.height < r1.top); @@ -149,8 +153,10 @@ export class MarqueeView extends React.Component this.marqueeInkDelete(ink.Data); } this.cleanupInteractions(); + e.stopPropagation(); } if (e.key === "c") { + e.stopPropagation(); let bounds = this.Bounds; let selected = this.marqueeSelect().map(d => { this.props.removeDocument(d); @@ -239,7 +245,7 @@ export class MarqueeView extends React.Component } render() { - return
+ return
{this.props.children} {!this._visible ? (null) : this.marqueeDiv}
; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 3a4425358..671bfbc04 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -134,7 +134,6 @@ export class CollectionFreeFormDocumentView extends React.Component { - e.stopPropagation(); this._downX = e.clientX; this._downY = e.clientY; document.removeEventListener("pointerup", this.onPointerUp); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 8922e4b81..efa291c0f 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -22,6 +22,7 @@ import { DocumentContentsView } from "./DocumentContentsView"; import "./DocumentView.scss"; import React = require("react"); import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; +import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; export interface DocumentViewProps { ContainingCollectionView: Opt; @@ -144,6 +145,13 @@ export class DocumentView extends React.Component { } } + onClick = (e: React.MouseEvent): void => { + console.log("click = " + this.props.Document.Title); + if (CurrentUserUtils.MainDocId != this.props.Document.Id) { + SelectionManager.SelectDoc(this, e.ctrlKey); + } + e.stopPropagation(); + } onPointerDown = (e: React.PointerEvent): void => { this._downX = e.clientX; this._downY = e.clientY; @@ -180,10 +188,6 @@ export class DocumentView extends React.Component { onPointerUp = (e: PointerEvent): void => { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); - if (!SelectionManager.IsSelected(this) && e.button !== 2 && - Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) { - SelectionManager.SelectDoc(this, e.ctrlKey); - } } deleteClicked = (): void => { @@ -304,7 +308,7 @@ export class DocumentView extends React.Component { width: nativeWidth, height: nativeHeight, transform: `scale(${scaling}, ${scaling})` }} - onDrop={this.onDrop} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} + onDrop={this.onDrop} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick} > {this.contents}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 29ed2da13..56c21dbd3 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -229,6 +229,10 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte } } + onClick = (e: React.MouseEvent): void => { + this._ref.current!.focus(); + } + tooltipTextMenuPlugin() { let myprops = this.props; return new Plugin({ @@ -255,7 +259,7 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte if (e.keyCode === 9) e.preventDefault(); // stop propagation doesn't seem to stop propagation of native keyboard events. // so we set a flag on the native event that marks that the event's been handled. - // (e.nativeEvent as any).DASHFormattedTextBoxHandled = true; + (e.nativeEvent as any).DASHFormattedTextBoxHandled = true; } render() { let style = this.props.isOverlay ? "scroll" : "hidden"; @@ -264,6 +268,7 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte onKeyDown={this.onKeyPress} onKeyPress={this.onKeyPress} onFocus={this.onFocused} + onClick={this.onClick} onPointerUp={this.onPointerUp} onPointerDown={this.onPointerDown} onContextMenu={this.specificContextMenu} -- cgit v1.2.3-70-g09d2 From 575d8b339cdf74cdcb8d46dcd6e627aec2dda636 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 24 Apr 2019 23:17:44 -0400 Subject: added borderRadius and fixed a bunch of broken props along the way. --- src/client/documents/Documents.ts | 2 ++ src/client/views/Main.scss | 3 ++- src/client/views/Main.tsx | 3 ++- src/client/views/MainOverlayTextBox.tsx | 4 ++-- src/client/views/collections/CollectionBaseView.tsx | 7 ++++--- src/client/views/collections/CollectionDockingView.tsx | 3 ++- src/client/views/collections/CollectionSchemaView.tsx | 6 +++++- src/client/views/collections/CollectionSubView.tsx | 1 + src/client/views/collections/CollectionTreeView.tsx | 5 ++++- .../collectionFreeForm/CollectionFreeFormView.scss | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 14 +++++++++++--- .../views/collections/collectionFreeForm/MarqueeView.tsx | 7 ++++--- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 11 +++++++++++ src/client/views/nodes/DocumentView.tsx | 2 ++ src/client/views/nodes/FieldView.tsx | 7 ++++++- src/client/views/nodes/FormattedTextBox.scss | 3 +-- src/client/views/nodes/FormattedTextBox.tsx | 5 ++++- src/client/views/nodes/ImageBox.scss | 3 --- src/client/views/nodes/ImageBox.tsx | 2 +- src/fields/KeyStore.ts | 3 ++- 20 files changed, 67 insertions(+), 25 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 0e6661819..879b114b6 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -55,6 +55,7 @@ export interface DocumentOptions { backgroundColor?: string; copyDraggedItems?: boolean; documentText?: string; + borderRounding?: number; } export namespace Documents { @@ -108,6 +109,7 @@ export namespace Documents { if (options.layout !== undefined) { doc.SetText(KeyStore.Layout, options.layout); } if (options.layoutKeys !== undefined) { doc.Set(KeyStore.LayoutKeys, new ListField(options.layoutKeys)); } if (options.copyDraggedItems !== undefined) { doc.SetBoolean(KeyStore.CopyDraggedItems, options.copyDraggedItems); } + if (options.borderRounding !== undefined) { doc.SetNumber(KeyStore.BorderRounding, options.borderRounding); } return doc; } diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss index 4373534b2..3edc79d39 100644 --- a/src/client/views/Main.scss +++ b/src/client/views/Main.scss @@ -42,7 +42,8 @@ h1 { } .jsx-parser { - width:100% + width:100%; + pointer-events: none; } p { diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 934616aca..057f68ed9 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -17,7 +17,7 @@ import { CurrentUserUtils } from '../../server/authentication/models/current_use import { MessageStore } from '../../server/Message'; import { RouteStore } from '../../server/RouteStore'; import { ServerUtils } from '../../server/ServerUtil'; -import { emptyDocFunction, emptyFunction, returnTrue, Utils, returnOne } from '../../Utils'; +import { emptyDocFunction, emptyFunction, returnTrue, Utils, returnOne, returnZero } from '../../Utils'; import { Documents } from '../documents/Documents'; import { ColumnAttributeModel } from '../northstar/core/attribute/AttributeModel'; import { AttributeTransformationModel } from '../northstar/core/attribute/AttributeTransformationModel'; @@ -197,6 +197,7 @@ export class Main extends React.Component { isTopMost={true} selectOnLoad={false} focus={emptyDocFunction} + borderRounding={returnZero} parentActive={returnTrue} whenActiveChanged={emptyFunction} ContainingCollectionView={undefined} />} diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index 9aaaad084..f98f6e8a5 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -5,7 +5,7 @@ import * as React from 'react'; import { Document } from '../../fields/Document'; import { Key } from '../../fields/Key'; import { KeyStore } from '../../fields/KeyStore'; -import { emptyDocFunction, emptyFunction, returnTrue } from '../../Utils'; +import { emptyDocFunction, emptyFunction, returnTrue, returnZero } from '../../Utils'; import '../northstar/model/ModelExtensions'; import '../northstar/utils/Extensions'; import { DragManager } from '../util/DragManager'; @@ -97,7 +97,7 @@ export class MainOverlayTextBox extends React.Component style={{ width: `${this.TextDoc.Width()}px`, height: `${this.TextDoc.Height()}px` }}> + ScreenToLocalTransform={this._textXf} borderRounding={returnZero} PanelWidth={returnZero} PanelHeight={returnZero} focus={emptyDocFunction} />
; } diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 097236c1d..e65770137 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -2,13 +2,12 @@ import { action, computed } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Document } from '../../../fields/Document'; -import { Field, FieldValue, FieldWaiting } from '../../../fields/Field'; +import { FieldValue, FieldWaiting } from '../../../fields/Field'; import { KeyStore } from '../../../fields/KeyStore'; import { ListField } from '../../../fields/ListField'; import { NumberField } from '../../../fields/NumberField'; import { ContextMenu } from '../ContextMenu'; import { FieldViewProps } from '../nodes/FieldView'; -import { TextField } from '../../../fields/TextField'; export enum CollectionViewType { Invalid, @@ -190,7 +189,9 @@ 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/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 84159635a..eb94a4e6d 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -8,7 +8,7 @@ import { Document } from "../../../fields/Document"; import { KeyStore } from "../../../fields/KeyStore"; import Measure from "react-measure"; import { FieldId, Opt, Field, FieldWaiting } from "../../../fields/Field"; -import { Utils, returnTrue, emptyFunction, emptyDocFunction, returnOne } from "../../../Utils"; +import { Utils, returnTrue, emptyFunction, emptyDocFunction, returnOne, returnZero } from "../../../Utils"; import { Server } from "../../Server"; import { undoBatch } from "../../util/UndoManager"; import { DocumentView } from "../nodes/DocumentView"; @@ -368,6 +368,7 @@ export class DockedFrameRenderer extends React.Component { parentActive={returnTrue} whenActiveChanged={emptyFunction} focus={emptyDocFunction} + borderRounding={returnZero} ContainingCollectionView={undefined} />
); } diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index cb7a67991..dc2910ede 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -12,7 +12,7 @@ import { Field, Opt } from "../../../fields/Field"; import { Key } from "../../../fields/Key"; import { KeyStore } from "../../../fields/KeyStore"; import { ListField } from "../../../fields/ListField"; -import { emptyDocFunction, emptyFunction, returnFalse } from "../../../Utils"; +import { emptyDocFunction, emptyFunction, returnFalse, returnZero } from "../../../Utils"; import { Server } from "../../Server"; import { SetupDrag } from "../../util/DragManager"; import { CompileScript, ToField } from "../../util/Scripting"; @@ -77,6 +77,9 @@ export class CollectionSchemaView extends CollectionSubView { focus: emptyDocFunction, active: returnFalse, whenActiveChanged: emptyFunction, + borderRounding: this.props.borderRounding, + PanelHeight: returnZero, + PanelWidth: returnZero, }; let contents = ( @@ -275,6 +278,7 @@ export class CollectionSchemaView extends CollectionSubView { focus={emptyDocFunction} parentActive={this.props.active} whenActiveChanged={this.props.whenActiveChanged} + borderRounding={this.props.borderRounding} />
boolean) => boolean; PanelWidth: () => number; PanelHeight: () => number; + borderRounding: () => number; } export interface SubCollectionViewProps extends CollectionViewProps { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index e0387f4b4..b9d1f0bd9 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -136,7 +136,10 @@ export class CollectionTreeView extends CollectionSubView { ); return ( -
e.stopPropagation()} onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}> +
e.stopPropagation()} + onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}>
.jsx-parser { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 7492d8744..9e2c9bf9a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -257,6 +257,7 @@ export class CollectionFreeFormView extends CollectionSubView { focus: this.focusDocument, parentActive: this.props.active, whenActiveChanged: this.props.active, + borderRounding: this.props.borderRounding, }; } @@ -288,11 +289,17 @@ export class CollectionFreeFormView extends CollectionSubView { const containerName = `collectionfreeformview${this.isAnnotationOverlay ? "-overlay" : "-container"}`; return (
- + + {this.props.Document.Title} + + */} + - @@ -340,6 +347,7 @@ interface CollectionFreeFormViewPannableContentsProps { panX: () => number; panY: () => number; zoomScaling: () => number; + borderRadius: () => number; } @observer @@ -350,7 +358,7 @@ class CollectionFreeFormViewPannableContents extends React.Component otherwise, reactions won't fire - return
+ return
{this.props.children}
; } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 898fff019..e724ab47e 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -14,7 +14,6 @@ import { CollectionFreeFormView } from "./CollectionFreeFormView"; import "./MarqueeView.scss"; import React = require("react"); import { Utils } from "../../../../Utils"; -import { ListField } from "../../../../fields/ListField"; interface MarqueeViewProps { getContainerTransform: () => Transform; @@ -25,6 +24,7 @@ interface MarqueeViewProps { selectDocuments: (docs: Document[]) => void; removeDocument: (doc: Document) => boolean; addLiveTextDocument: (doc: Document) => void; + borderRadius: () => number; } @observer @@ -138,7 +138,7 @@ export class MarqueeView extends React.Component this.cleanupInteractions(true); e.stopPropagation(); } - if (e.key === "c" || e.key === "r") { + if (e.key === "c" || e.key === "r" || e.key === "e") { e.stopPropagation(); let bounds = this.Bounds; let selected = this.marqueeSelect().map(d => { @@ -156,6 +156,7 @@ export class MarqueeView extends React.Component y: bounds.top, panx: 0, pany: 0, + borderRounding: e.key === "e" ? -1 : undefined, backgroundColor: selected.length ? "white" : "", scale: zoomBasis, width: bounds.width * zoomBasis, @@ -250,7 +251,7 @@ export class MarqueeView extends React.Component } render() { - return
+ return
{this.props.children} {!this._visible ? (null) : this.marqueeDiv}
; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 420324d40..8caf5ff31 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -65,6 +65,7 @@ export class CollectionFreeFormDocumentView extends React.Component; } @@ -148,6 +149,15 @@ export class CollectionFreeFormDocumentView extends React.Component { + let br = this.props.Document.GetNumber(KeyStore.BorderRounding, 0); + return br >= 0 ? br : + this.props.Document.GetNumber(KeyStore.NativeWidth, 0) === 0 ? + Math.min(this.props.PanelWidth(), this.props.PanelHeight()) + : + Math.min(this.props.Document.GetNumber(KeyStore.NativeWidth, 0), this.props.Document.GetNumber(KeyStore.NativeHeight, 0)); + } + render() { let maximizedDoc = this.props.Document.GetT(KeyStore.MaximizedDoc, Document); let zoomFade = 1; @@ -168,6 +178,7 @@ export class CollectionFreeFormDocumentView extends React.Component boolean; whenActiveChanged: (isActive: boolean) => void; toggleMinimized: () => void; + borderRounding: () => number; } export interface JsxArgs extends DocumentViewProps { Keys: { [name: string]: Key }; @@ -277,6 +278,7 @@ export class DocumentView extends React.Component {
boolean; whenActiveChanged: (isActive: boolean) => void; focus: (doc: Document) => void; + PanelWidth: () => number; + PanelHeight: () => number; + borderRounding: () => number; } @observer @@ -100,6 +103,8 @@ export class FieldView extends React.Component { layoutKey={KeyStore.Layout} ContainingCollectionView={this.props.ContainingCollectionView} parentActive={this.props.active} + borderRounding={returnZero} + toggleMinimized={emptyFunction} whenActiveChanged={this.props.whenActiveChanged} /> ); } diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 5eb2bf7ce..59857bab3 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -22,11 +22,10 @@ overflow-x: hidden; color: initial; height: 100%; - pointer-events: all; + pointer-events: none; } .formattedTextBox-cont-hidden { overflow: hidden; - pointer-events: none; } .menuicon { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 9cd58c73a..4b2fdbaff 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -273,7 +273,10 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte let color = this.props.Document.GetText(KeyStore.BackgroundColor, ""); return (
{ let nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 1); let interactive = InkingControl.Instance.selectedTool ? "" : "interactive" return ( -
+
Image not found {paths.length > 1 ? this.dots(paths) : (null)} {this.lightbox(paths)} diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index 0a96beb50..aa18a9f33 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -49,12 +49,13 @@ export namespace KeyStore { export const MinimizedDoc = new Key("MinimizedDoc"); export const MaximizedDoc = new Key("MaximizedDoc"); export const CopyDraggedItems = new Key("CopyDraggedItems"); + export const BorderRounding = new Key("BorderRounding"); export const KeyList: Key[] = [Prototype, X, Y, Page, Title, Author, PanX, PanY, Scale, NativeWidth, NativeHeight, Width, Height, ZIndex, ZoomBasis, Data, Annotations, ViewType, Layout, BackgroundColor, BackgroundLayout, OverlayLayout, LayoutKeys, LayoutFields, ColumnsKey, SchemaSplitPercentage, Caption, ActiveWorkspace, DocumentText, BrushingDocs, LinkedToDocs, LinkedFromDocs, LinkDescription, LinkTags, Thumbnail, ThumbnailPage, CurPage, AnnotationOn, NumPages, Ink, Cursors, OptionalRightCollection, - Archives, Workspaces, IsMinimized, MinimizedDoc, MaximizedDoc, CopyDraggedItems + Archives, Workspaces, IsMinimized, MinimizedDoc, MaximizedDoc, CopyDraggedItems, BorderRounding ]; export function KeyLookup(keyid: string) { for (const key of KeyList) { -- cgit v1.2.3-70-g09d2 From e1a65c5fa52dd094cc48c0c85b3c92ae8789666d Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Thu, 25 Apr 2019 01:26:28 -0400 Subject: Bunch of files --- src/client/DocServer.ts | 4 + src/client/Server.ts | 173 --------------------- src/client/SocketStub.ts | 69 -------- src/client/util/Scripting.ts | 33 +--- .../views/collections/CollectionBaseView.tsx | 76 +++++---- src/client/views/nodes/LinkMenu.tsx | 26 ++-- .../authentication/models/current_user_utils.ts | 28 ++-- 7 files changed, 73 insertions(+), 336 deletions(-) delete mode 100644 src/client/Server.ts delete mode 100644 src/client/SocketStub.ts (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index cba0c4770..02fd28a86 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -9,6 +9,10 @@ export namespace DocServer { const _socket = OpenSocket(`${window.location.protocol}//${window.location.hostname}:4321`); const GUID: string = Utils.GenerateGuid(); + export function prepend(extension: string): string { + return window.location.origin + extension; + } + export async function GetRefField(id: string): Promise> { let cached = _cache[id]; if (cached === undefined) { diff --git a/src/client/Server.ts b/src/client/Server.ts deleted file mode 100644 index 66e9878d9..000000000 --- a/src/client/Server.ts +++ /dev/null @@ -1,173 +0,0 @@ -import { Key } from "../fields/Key"; -import { ObservableMap, action, reaction, runInAction } from "mobx"; -import { Field, FieldWaiting, FIELD_WAITING, Opt, FieldId } from "../fields/Field"; -import { Document } from "../fields/Document"; -import { SocketStub, FieldMap } from "./SocketStub"; -import * as OpenSocket from 'socket.io-client'; -import { Utils, emptyFunction } from "./../Utils"; -import { MessageStore, Types } from "./../server/Message"; - -export class Server { - public static ClientFieldsCached: ObservableMap = new ObservableMap(); - static Socket: SocketIOClient.Socket = OpenSocket(`${window.location.protocol}//${window.location.hostname}:4321`); - static GUID: string = Utils.GenerateGuid(); - - // Retrieves the cached value of the field and sends a request to the server for the real value (if it's not cached). - // Call this is from within a reaction and test whether the return value is FieldWaiting. - public static GetField(fieldid: FieldId): Promise>; - public static GetField(fieldid: FieldId, callback: (field: Opt) => void): void; - public static GetField(fieldid: FieldId, callback?: (field: Opt) => void): Promise> | void { - let fn = (cb: (field: Opt) => void) => { - - let cached = this.ClientFieldsCached.get(fieldid); - if (cached === undefined) { - this.ClientFieldsCached.set(fieldid, FieldWaiting); - SocketStub.SEND_FIELD_REQUEST(fieldid, action((field: Field | undefined) => { - let cached = this.ClientFieldsCached.get(fieldid); - if (cached !== FieldWaiting) { - cb(cached); - } - else { - if (field) { - this.ClientFieldsCached.set(fieldid, field); - } else { - this.ClientFieldsCached.delete(fieldid); - } - cb(field); - } - })); - } else if (cached !== FieldWaiting) { - setTimeout(() => cb(cached as Field), 0); - } else { - reaction(() => this.ClientFieldsCached.get(fieldid), - (field, reaction) => { - if (field !== FieldWaiting) { - reaction.dispose(); - cb(field); - } - }); - } - }; - if (callback) { - fn(callback); - } else { - return new Promise(fn); - } - } - - public static GetFields(fieldIds: FieldId[]): Promise<{ [id: string]: Field }>; - public static GetFields(fieldIds: FieldId[], callback: (fields: FieldMap) => any): void; - public static GetFields(fieldIds: FieldId[], callback?: (fields: FieldMap) => any): Promise | void { - let fn = action((cb: (fields: FieldMap) => void) => { - - let neededFieldIds: FieldId[] = []; - let waitingFieldIds: FieldId[] = []; - let existingFields: FieldMap = {}; - for (let id of fieldIds) { - let field = this.ClientFieldsCached.get(id); - if (field === undefined) { - neededFieldIds.push(id); - this.ClientFieldsCached.set(id, FieldWaiting); - } else if (field === FieldWaiting) { - waitingFieldIds.push(id); - } else { - existingFields[id] = field; - } - } - SocketStub.SEND_FIELDS_REQUEST(neededFieldIds, action((fields: FieldMap) => { - for (let id of neededFieldIds) { - let field = fields[id]; - if (field) { - if (this.ClientFieldsCached.get(field.Id) === FieldWaiting) { - this.ClientFieldsCached.set(field.Id, field); - } else { - throw new Error("we shouldn't be trying to replace things that are already in the cache"); - } - } else { - if (this.ClientFieldsCached.get(id) === FieldWaiting) { - this.ClientFieldsCached.delete(id); - } else { - throw new Error("we shouldn't be trying to replace things that are already in the cache"); - } - } - } - reaction(() => waitingFieldIds.map(id => this.ClientFieldsCached.get(id)), - (cachedFields, reaction) => { - if (!cachedFields.some(field => field === FieldWaiting)) { - const realFields = cachedFields as Opt[]; - reaction.dispose(); - waitingFieldIds.forEach((id, index) => { - existingFields[id] = realFields[index]; - }); - cb({ ...fields, ...existingFields }); - } - }, { fireImmediately: true }); - })); - }); - if (callback) { - fn(callback); - } else { - return new Promise(fn); - } - } - - public static GetDocumentField(doc: Document, key: Key, callback?: (field: Field) => void) { - let field = doc._proxies.get(key.Id); - if (field) { - this.GetField(field, - action((fieldfromserver: Opt) => { - if (fieldfromserver) { - doc.fields.set(key.Id, { key, field: fieldfromserver }); - if (callback) { - callback(fieldfromserver); - } - } - })); - } - } - - public static DeleteDocumentField(doc: Document, key: Key) { - SocketStub.SEND_DELETE_DOCUMENT_FIELD(doc, key); - } - - public static UpdateField(field: Field) { - if (!this.ClientFieldsCached.has(field.Id)) { - this.ClientFieldsCached.set(field.Id, field); - } - SocketStub.SEND_SET_FIELD(field); - } - - static connected(message: string) { - Server.Socket.emit(MessageStore.Bar.Message, Server.GUID); - } - - @action - private static cacheField(clientField: Field) { - var cached = this.ClientFieldsCached.get(clientField.Id); - if (!cached) { - this.ClientFieldsCached.set(clientField.Id, clientField); - } else { - // probably should overwrite the values within any field that was already here... - } - return this.ClientFieldsCached.get(clientField.Id); - } - - @action - static updateField(field: { id: string, data: any, type: Types }) { - if (Server.ClientFieldsCached.has(field.id)) { - var f = Server.ClientFieldsCached.get(field.id); - if (f) { - // console.log("Applying : " + field.id); - f.UpdateFromServer(field.data); - f.init(emptyFunction); - } else { - // console.log("Not applying wa : " + field.id); - } - } else { - // console.log("Not applying mi : " + field.id); - } - } -} - -Utils.AddServerHandler(Server.Socket, MessageStore.Foo, Server.connected); -Utils.AddServerHandler(Server.Socket, MessageStore.SetField, Server.updateField); diff --git a/src/client/SocketStub.ts b/src/client/SocketStub.ts deleted file mode 100644 index 382a81f66..000000000 --- a/src/client/SocketStub.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { Key } from "../fields/Key"; -import { Field, FieldId, Opt } from "../fields/Field"; -import { ObservableMap } from "mobx"; -import { Document } from "../fields/Document"; -import { MessageStore, Transferable } from "../server/Message"; -import { Utils } from "../Utils"; -import { Server } from "./Server"; -import { ServerUtils } from "../server/ServerUtil"; - - -export interface FieldMap { - [id: string]: Opt; -} - -//TODO tfs: I think it might be cleaner to not have SocketStub deal with turning what the server gives it into Fields (in other words not call ServerUtils.FromJson), and leave that for the Server class. -export class SocketStub { - - static FieldStore: ObservableMap = new ObservableMap(); - - public static SEND_FIELD_REQUEST(fieldid: FieldId): Promise>; - public static SEND_FIELD_REQUEST(fieldid: FieldId, callback: (field: Opt) => void): void; - public static SEND_FIELD_REQUEST(fieldid: FieldId, callback?: (field: Opt) => void): Promise> | void { - let fn = function (cb: (field: Opt) => void) { - Utils.EmitCallback(Server.Socket, MessageStore.GetField, fieldid, (field: Transferable) => { - if (field) { - ServerUtils.FromJson(field).init(cb); - } else { - cb(undefined); - } - }); - }; - if (callback) { - fn(callback); - } else { - return new Promise(fn); - } - } - - public static SEND_FIELDS_REQUEST(fieldIds: FieldId[], callback: (fields: FieldMap) => any) { - Utils.EmitCallback(Server.Socket, MessageStore.GetFields, fieldIds, (fields: Transferable[]) => { - let fieldMap: FieldMap = {}; - fields.map(field => fieldMap[field.id] = ServerUtils.FromJson(field)); - let proms = Object.values(fieldMap).map(val => - new Promise(resolve => val!.init(resolve))); - Promise.all(proms).then(() => callback(fieldMap)); - }); - } - - public static SEND_DELETE_DOCUMENT_FIELD(doc: Document, key: Key) { - // Send a request to delete the field stored under the specified key from the document - - // ...SOCKET(DELETE_DOCUMENT_FIELD, document id, key id) - - // Server removes the field id from the document's list of field proxies - var document = this.FieldStore.get(doc.Id) as Document; - if (document) { - document._proxies.delete(key.Id); - } - } - - public static SEND_SET_FIELD(field: Field) { - // Send a request to set the value of a field - - // ...SOCKET(SET_FIELD, field id, serialized field value) - - // Server updates the value of the field in its fieldstore - Utils.Emit(Server.Socket, MessageStore.SetField, field.ToJson()); - } -} diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index c67cc067a..dbec82340 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -1,13 +1,5 @@ // import * as ts from "typescript" let ts = (window as any).ts; -import { Opt, Field } from "../../fields/Field"; -import { Document } from "../../fields/Document"; -import { NumberField } from "../../fields/NumberField"; -import { ImageField } from "../../fields/ImageField"; -import { TextField } from "../../fields/TextField"; -import { RichTextField } from "../../fields/RichTextField"; -import { KeyStore } from "../../fields/KeyStore"; -import { ListField } from "../../fields/ListField"; // // @ts-ignore // import * as typescriptlib from '!!raw-loader!../../../node_modules/typescript/lib/lib.d.ts' // // @ts-ignore @@ -15,8 +7,10 @@ import { ListField } from "../../fields/ListField"; // @ts-ignore import * as typescriptlib from '!!raw-loader!./type_decls.d'; -import { Documents } from "../documents/Documents"; -import { Key } from "../../fields/Key"; +import { Docs } from "../documents/Documents"; +import { Doc, Field } from '../../new_fields/Doc'; +import { ImageField, PdfField, VideoField, AudioField } from '../../new_fields/URLField'; +import { List } from '../../new_fields/List'; export interface ScriptSucccess { success: true; @@ -50,9 +44,9 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an return { compiled: false, errors: diagnostics }; } - let fieldTypes = [Document, NumberField, TextField, ImageField, RichTextField, ListField, Key]; - let paramNames = ["KeyStore", "Documents", ...fieldTypes.map(fn => fn.name)]; - let params: any[] = [KeyStore, Documents, ...fieldTypes]; + let fieldTypes = [Doc, ImageField, PdfField, VideoField, AudioField, List, RichTextField]; + let paramNames = ["Docs", ...fieldTypes.map(fn => fn.name)]; + let params: any[] = [Docs, ...fieldTypes]; let compiledFunction = new Function(...paramNames, `return ${script}`); let { capturedVariables = {} } = options; let run = (args: { [name: string]: any } = {}): ScriptResult => { @@ -171,17 +165,4 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp let diagnostics = ts.getPreEmitDiagnostics(program).concat(testResult.diagnostics); return Run(outputText, paramNames, diagnostics, script, options); -} - -export function OrLiteralType(returnType: string): string { - return `${returnType} | string | number`; -} - -export function ToField(data: any): Opt { - if (typeof data === "string") { - return new TextField(data); - } else if (typeof data === "number") { - return new NumberField(data); - } - return undefined; } \ No newline at end of file diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 4755b2d57..058893198 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -1,13 +1,12 @@ import { action, computed } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Document } from '../../../fields/Document'; -import { Field, FieldValue, FieldWaiting } from '../../../fields/Field'; -import { KeyStore } from '../../../fields/KeyStore'; -import { ListField } from '../../../fields/ListField'; -import { NumberField } from '../../../fields/NumberField'; import { ContextMenu } from '../ContextMenu'; import { FieldViewProps } from '../nodes/FieldView'; +import { Cast, FieldValue, PromiseValue } from '../../../new_fields/Types'; +import { Doc, FieldResult, Opt, Id } from '../../../new_fields/Doc'; +import { listSpec } from '../../../new_fields/Schema'; +import { List } from '../../../new_fields/List'; export enum CollectionViewType { Invalid, @@ -18,9 +17,9 @@ export enum CollectionViewType { } export interface CollectionRenderProps { - addDocument: (document: Document, allowDuplicates?: boolean) => boolean; - removeDocument: (document: Document) => boolean; - moveDocument: (document: Document, targetCollection: Document, addDocument: (document: Document) => boolean) => boolean; + addDocument: (document: Doc, allowDuplicates?: boolean) => boolean; + removeDocument: (document: Doc) => boolean; + moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean; active: () => boolean; whenActiveChanged: (isActive: boolean) => void; } @@ -37,11 +36,9 @@ export interface CollectionViewProps extends FieldViewProps { export class CollectionBaseView extends React.Component { get collectionViewType(): CollectionViewType | undefined { let Document = this.props.Document; - let viewField = Document.GetT(KeyStore.ViewType, NumberField); - if (viewField === FieldWaiting) { - return undefined; - } else if (viewField) { - return viewField.Data; + let viewField = Cast(Document.viewType, "number"); + if (viewField !== undefined) { + return viewField; } else { return CollectionViewType.Invalid; } @@ -60,47 +57,48 @@ export class CollectionBaseView extends React.Component { this.props.whenActiveChanged(isActive); } - createsCycle(documentToAdd: Document, containerDocument: Document): boolean { - if (!(documentToAdd instanceof Document)) { + createsCycle(documentToAdd: Doc, containerDocument: Doc): boolean { + if (!(documentToAdd instanceof Doc)) { return false; } - let data = documentToAdd.GetList(KeyStore.Data, [] as Document[]); + let data = Cast(documentToAdd.data, listSpec(Doc), []); for (const doc of data.filter(d => d instanceof Document)) { if (this.createsCycle(doc, containerDocument)) { return true; } } - let annots = documentToAdd.GetList(KeyStore.Annotations, [] as Document[]); + let annots = Cast(documentToAdd.annotations, listSpec(Doc), []); for (const annot of annots) { if (this.createsCycle(annot, containerDocument)) { return true; } } - for (let containerProto: FieldValue = containerDocument; containerProto && containerProto !== FieldWaiting; containerProto = containerProto.GetPrototype()) { - if (containerProto.Id === documentToAdd.Id) { + for (let containerProto: Opt = containerDocument; containerProto !== undefined; containerProto = FieldValue(containerProto.proto)) { + if (containerProto[Id] === documentToAdd[Id]) { return true; } } return false; } - @computed get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey.Id === KeyStore.Annotations.Id; } // bcz: ? Why do we need to compare Id's? + @computed get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey === "annotations"; } @action.bound - addDocument(doc: Document, allowDuplicates: boolean = false): boolean { + addDocument(doc: Doc, allowDuplicates: boolean = false): boolean { let props = this.props; - var curPage = props.Document.GetNumber(KeyStore.CurPage, -1); - doc.SetOnPrototype(KeyStore.Page, new NumberField(curPage)); + var curPage = Cast(props.Document.curPage, "number", -1); + Doc.SetOnPrototype(doc, "page", curPage); if (true || this.isAnnotationOverlay) { - doc.SetNumber(KeyStore.Zoom, this.props.Document.GetNumber(KeyStore.Scale, 1)); + doc.zoom = Cast(this.props.Document.scale, "number", 1); } if (curPage >= 0) { - doc.SetOnPrototype(KeyStore.AnnotationOn, props.Document); + Doc.SetOnPrototype(doc, "annotationOn", props.Document); } - if (props.Document.Get(props.fieldKey) instanceof Field) { + const data = props.Document[props.fieldKey]; + if (data !== undefined) { //TODO This won't create the field if it doesn't already exist - const value = props.Document.GetData(props.fieldKey, ListField, new Array()); - if (!this.createsCycle(doc, props.Document)) { - if (!value.some(v => v.Id === doc.Id) || allowDuplicates) { + const value = Cast(data, listSpec(Doc)); + if (!this.createsCycle(doc, props.Document) && value !== undefined) { + if (allowDuplicates || !value.some(v => v.Id === doc.Id)) { value.push(doc); } } @@ -108,9 +106,9 @@ export class CollectionBaseView extends React.Component { return false; } } else { - let proto = props.Document.GetPrototype(); - if (!proto || proto === FieldWaiting || !this.createsCycle(proto, doc)) { - const field = new ListField([doc]); + let proto = FieldValue(props.Document.proto); + if (!proto || !this.createsCycle(proto, doc)) { + const field = new List([doc]); // const script = CompileScript(` // if(added) { // console.log("added " + field.Title + " " + doc.Title); @@ -130,7 +128,7 @@ export class CollectionBaseView extends React.Component { // if (script.compiled) { // field.addScript(new ScriptField(script)); // } - props.Document.SetOnPrototype(props.fieldKey, field); + Doc.SetOnPrototype(props.Document, props.fieldKey, field); } else { return false; @@ -140,20 +138,20 @@ export class CollectionBaseView extends React.Component { } @action.bound - removeDocument(doc: Document): boolean { + removeDocument(doc: Doc): boolean { const props = this.props; //TODO This won't create the field if it doesn't already exist - const value = props.Document.GetData(props.fieldKey, ListField, new Array()); + const value = Cast(props.Document[props.fieldKey], listSpec(Doc), []); let index = -1; for (let i = 0; i < value.length; i++) { - if (value[i].Id === doc.Id) { + if (value[i][Id] === doc[Id]) { index = i; break; } } - doc.GetTAsync(KeyStore.AnnotationOn, Document).then((annotationOn) => { + PromiseValue(Cast(doc.annotationOn, Doc)).then((annotationOn) => { if (annotationOn === props.Document) { - doc.Set(KeyStore.AnnotationOn, undefined, true); + doc.annotationOn = undefined; } }); @@ -168,7 +166,7 @@ export class CollectionBaseView extends React.Component { } @action.bound - moveDocument(doc: Document, targetCollection: Document, addDocument: (doc: Document) => boolean): boolean { + moveDocument(doc: Doc, targetCollection: Doc, addDocument: (doc: Doc) => boolean): boolean { if (this.props.Document === targetCollection) { return true; } diff --git a/src/client/views/nodes/LinkMenu.tsx b/src/client/views/nodes/LinkMenu.tsx index ac09da305..3ecc8555d 100644 --- a/src/client/views/nodes/LinkMenu.tsx +++ b/src/client/views/nodes/LinkMenu.tsx @@ -1,15 +1,13 @@ import { action, observable } from "mobx"; import { observer } from "mobx-react"; -import { Document } from "../../../fields/Document"; -import { FieldWaiting } from "../../../fields/Field"; -import { Key } from "../../../fields/Key"; -import { KeyStore } from '../../../fields/KeyStore'; -import { ListField } from "../../../fields/ListField"; import { DocumentView } from "./DocumentView"; import { LinkBox } from "./LinkBox"; import { LinkEditor } from "./LinkEditor"; import './LinkMenu.scss'; import React = require("react"); +import { Doc, Id } from "../../../new_fields/Doc"; +import { Cast, FieldValue } from "../../../new_fields/Types"; +import { listSpec } from "../../../new_fields/Schema"; interface Props { docView: DocumentView; @@ -19,28 +17,28 @@ interface Props { @observer export class LinkMenu extends React.Component { - @observable private _editingLink?: Document; + @observable private _editingLink?: Doc; - renderLinkItems(links: Document[], key: Key, type: string) { + renderLinkItems(links: Doc[], key: string, type: string) { return links.map(link => { - let doc = link.GetT(key, Document); - if (doc && doc !== FieldWaiting) { - return this._editingLink = link)} type={type} />; + let doc = FieldValue(Cast(link[key], Doc)); + if (doc) { + return this._editingLink = link)} type={type} />; } }); } render() { //get list of links from document - let linkFrom: Document[] = this.props.docView.props.Document.GetData(KeyStore.LinkedFromDocs, ListField, []); - let linkTo: Document[] = this.props.docView.props.Document.GetData(KeyStore.LinkedToDocs, ListField, []); + let linkFrom: Doc[] = Cast(this.props.docView.props.Document.linkedFromDocs, listSpec(Doc), []); + let linkTo: Doc[] = Cast(this.props.docView.props.Document.linkedToDocs, listSpec(Doc), []); if (this._editingLink === undefined) { return (
- {this.renderLinkItems(linkTo, KeyStore.LinkedToDocs, "Destination: ")} - {this.renderLinkItems(linkFrom, KeyStore.LinkedFromDocs, "Source: ")} + {this.renderLinkItems(linkTo, "linkedTo", "Destination: ")} + {this.renderLinkItems(linkFrom, "linkedFrom", "Source: ")}
); diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index 5d4479c88..30a8980ae 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -1,19 +1,17 @@ import { computed, observable, action, runInAction } from "mobx"; import * as rp from 'request-promise'; -import { Documents } from "../../../client/documents/Documents"; +import { Docs } from "../../../client/documents/Documents"; import { Attribute, AttributeGroup, Catalog, Schema } from "../../../client/northstar/model/idea/idea"; import { ArrayUtil } from "../../../client/northstar/utils/ArrayUtil"; -import { Server } from "../../../client/Server"; -import { Document } from "../../../fields/Document"; -import { KeyStore } from "../../../fields/KeyStore"; -import { ListField } from "../../../fields/ListField"; import { RouteStore } from "../../RouteStore"; -import { ServerUtils } from "../../ServerUtil"; +import { DocServer } from "../../../client/DocServer"; +import { Doc } from "../../../new_fields/Doc"; +import { List } from "../../../new_fields/List"; export class CurrentUserUtils { private static curr_email: string; private static curr_id: string; - @observable private static user_document: Document; + @observable private static user_document: Doc; //TODO tfs: these should be temporary... private static mainDocId: string | undefined; @@ -23,15 +21,15 @@ export class CurrentUserUtils { public static get MainDocId() { return this.mainDocId; } public static set MainDocId(id: string | undefined) { this.mainDocId = id; } - private static createUserDocument(id: string): Document { - let doc = new Document(id); - doc.Set(KeyStore.Workspaces, new ListField()); - doc.Set(KeyStore.OptionalRightCollection, Documents.SchemaDocument([], { title: "Pending documents" })); + private static createUserDocument(id: string): Doc { + let doc = new Doc(id, true); + doc.workspaces = new List(); + doc.optionalRightCollection = Docs.SchemaDocument([], { title: "Pending documents" }); return doc; } public static loadCurrentUser(): Promise { - let userPromise = rp.get(ServerUtils.prepend(RouteStore.getCurrUser)).then(response => { + let userPromise = rp.get(DocServer.prepend(RouteStore.getCurrUser)).then(response => { if (response) { let obj = JSON.parse(response); CurrentUserUtils.curr_id = obj.id as string; @@ -40,10 +38,10 @@ export class CurrentUserUtils { throw new Error("There should be a user! Why does Dash think there isn't one?"); } }); - let userDocPromise = rp.get(ServerUtils.prepend(RouteStore.getUserDocumentId)).then(id => { + let userDocPromise = rp.get(DocServer.prepend(RouteStore.getUserDocumentId)).then(id => { if (id) { - return Server.GetField(id).then(field => - runInAction(() => this.user_document = field instanceof Document ? field : this.createUserDocument(id))); + return DocServer.GetRefField(id).then(field => + runInAction(() => this.user_document = field instanceof Doc ? field : this.createUserDocument(id))); } else { throw new Error("There should be a user id! Why does Dash think there isn't one?"); } -- cgit v1.2.3-70-g09d2 From 6a62e0a16abc3bbadfb179750463e3d361f1c759 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 25 Apr 2019 09:15:22 -0400 Subject: silly me - borderRadius can be inherited --- src/client/views/Main.scss | 1 + src/client/views/Main.tsx | 1 - src/client/views/MainOverlayTextBox.tsx | 2 +- src/client/views/collections/CollectionBaseView.tsx | 2 +- src/client/views/collections/CollectionDockingView.tsx | 1 - src/client/views/collections/CollectionSchemaView.tsx | 2 -- src/client/views/collections/CollectionSubView.tsx | 1 - src/client/views/collections/CollectionTreeView.tsx | 2 +- .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 10 ++++------ .../views/collections/collectionFreeForm/MarqueeView.tsx | 3 +-- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 1 - src/client/views/nodes/DocumentView.tsx | 3 +-- src/client/views/nodes/FieldView.tsx | 2 -- src/client/views/nodes/FormattedTextBox.tsx | 2 +- 14 files changed, 11 insertions(+), 22 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss index 3edc79d39..2f899ff28 100644 --- a/src/client/views/Main.scss +++ b/src/client/views/Main.scss @@ -44,6 +44,7 @@ h1 { .jsx-parser { width:100%; pointer-events: none; + border-radius: inherit; } p { diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 057f68ed9..c6b3f06d8 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -197,7 +197,6 @@ export class Main extends React.Component { isTopMost={true} selectOnLoad={false} focus={emptyDocFunction} - borderRounding={returnZero} parentActive={returnTrue} whenActiveChanged={emptyFunction} ContainingCollectionView={undefined} />} diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index f98f6e8a5..be8d67925 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -97,7 +97,7 @@ export class MainOverlayTextBox extends React.Component style={{ width: `${this.TextDoc.Width()}px`, height: `${this.TextDoc.Height()}px` }}> + ScreenToLocalTransform={this._textXf} PanelWidth={returnZero} PanelHeight={returnZero} focus={emptyDocFunction} />
; } diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index e65770137..87b767c93 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -190,7 +190,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/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index eb94a4e6d..3267f2455 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -368,7 +368,6 @@ export class DockedFrameRenderer extends React.Component { parentActive={returnTrue} whenActiveChanged={emptyFunction} focus={emptyDocFunction} - borderRounding={returnZero} ContainingCollectionView={undefined} />
); } diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index dc2910ede..b6d5f1bfa 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -77,7 +77,6 @@ export class CollectionSchemaView extends CollectionSubView { focus: emptyDocFunction, active: returnFalse, whenActiveChanged: emptyFunction, - borderRounding: this.props.borderRounding, PanelHeight: returnZero, PanelWidth: returnZero, }; @@ -278,7 +277,6 @@ export class CollectionSchemaView extends CollectionSubView { focus={emptyDocFunction} parentActive={this.props.active} whenActiveChanged={this.props.whenActiveChanged} - borderRounding={this.props.borderRounding} />
boolean) => boolean; PanelWidth: () => number; PanelHeight: () => number; - borderRounding: () => number; } export interface SubCollectionViewProps extends CollectionViewProps { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index b9d1f0bd9..905b48db7 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -137,7 +137,7 @@ export class CollectionTreeView extends CollectionSubView { return (
e.stopPropagation()} onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createDropTarget}>
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9e2c9bf9a..56342c84c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -257,7 +257,6 @@ export class CollectionFreeFormView extends CollectionSubView { focus: this.focusDocument, parentActive: this.props.active, whenActiveChanged: this.props.active, - borderRounding: this.props.borderRounding, }; } @@ -289,17 +288,17 @@ export class CollectionFreeFormView extends CollectionSubView { const containerName = `collectionfreeformview${this.isAnnotationOverlay ? "-overlay" : "-container"}`; return (
{/* {this.props.Document.Title} */} - - @@ -347,7 +346,6 @@ interface CollectionFreeFormViewPannableContentsProps { panX: () => number; panY: () => number; zoomScaling: () => number; - borderRadius: () => number; } @observer @@ -358,7 +356,7 @@ class CollectionFreeFormViewPannableContents extends React.Component otherwise, reactions won't fire - return
+ return
{this.props.children}
; } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index e724ab47e..b511a6e3d 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -24,7 +24,6 @@ interface MarqueeViewProps { selectDocuments: (docs: Document[]) => void; removeDocument: (doc: Document) => boolean; addLiveTextDocument: (doc: Document) => void; - borderRadius: () => number; } @observer @@ -251,7 +250,7 @@ export class MarqueeView extends React.Component } render() { - return
+ return
{this.props.children} {!this._visible ? (null) : this.marqueeDiv}
; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 8caf5ff31..4537ce3eb 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -65,7 +65,6 @@ export class CollectionFreeFormDocumentView extends React.Component; } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index ddf99c109..cec6e6468 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -41,7 +41,6 @@ export interface DocumentViewProps { parentActive: () => boolean; whenActiveChanged: (isActive: boolean) => void; toggleMinimized: () => void; - borderRounding: () => number; } export interface JsxArgs extends DocumentViewProps { Keys: { [name: string]: Key }; @@ -278,7 +277,7 @@ export class DocumentView extends React.Component {
void; PanelWidth: () => number; PanelHeight: () => number; - borderRounding: () => number; } @observer @@ -103,7 +102,6 @@ export class FieldView extends React.Component { layoutKey={KeyStore.Layout} ContainingCollectionView={this.props.ContainingCollectionView} parentActive={this.props.active} - borderRounding={returnZero} toggleMinimized={emptyFunction} whenActiveChanged={this.props.whenActiveChanged} /> ); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 4b2fdbaff..5b17763e7 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -274,7 +274,7 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte return (
Date: Sat, 27 Apr 2019 00:41:29 -0400 Subject: fixed various interactions with marquee --- src/client/views/collections/CollectionBaseView.tsx | 3 +-- .../collections/collectionFreeForm/MarqueeView.tsx | 18 ++++++++++++------ 2 files changed, 13 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 87b767c93..6cb650770 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -104,8 +104,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 (this.collectionViewType === CollectionViewType.Freeform || this.collectionViewType === CollectionViewType.Invalid) { let zoom = this.props.Document.GetNumber(KeyStore.Scale, 1); - let screen = this.props.ScreenToLocalTransform().inverse().Scale / (this.props as any).ContentScaling() * zoom; - doc.SetNumber(KeyStore.ZoomBasis, screen); + doc.SetNumber(KeyStore.ZoomBasis, zoom); } } return true; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 0e2ac0a80..89308d573 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -35,12 +35,13 @@ export class MarqueeView extends React.Component @observable _downX: number = 0; @observable _downY: number = 0; @observable _visible: boolean = false; + _commandExecuted = false; @action cleanupInteractions = (all: boolean = false) => { if (all) { - document.removeEventListener("pointermove", this.onPointerMove, true); document.removeEventListener("pointerup", this.onPointerUp, true); + document.removeEventListener("pointermove", this.onPointerMove, true); } document.removeEventListener("keydown", this.marqueeCommand, true); this._visible = false; @@ -58,6 +59,7 @@ export class MarqueeView extends React.Component onPointerDown = (e: React.PointerEvent): void => { this._downX = this._lastX = e.pageX; 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())) { @@ -130,17 +132,21 @@ export class MarqueeView extends React.Component @undoBatch @action marqueeCommand = (e: KeyboardEvent) => { + if (this._commandExecuted) { + return; + } if (e.key === "Backspace" || e.key === "Delete" || e.key == "d") { + this._commandExecuted = true; this.marqueeSelect().map(d => this.props.removeDocument(d)); let ink = this.props.container.props.Document.GetT(KeyStore.Ink, InkField); if (ink && ink !== FieldWaiting) { this.marqueeInkDelete(ink.Data); } - this.cleanupInteractions(true); + this.cleanupInteractions(false); e.stopPropagation(); } if (e.key === "c" || e.key === "r" || e.key === "e") { - console.log("DO MARQUEE"); + this._commandExecuted = true; e.stopPropagation(); let bounds = this.Bounds; let selected = this.marqueeSelect().map(d => { @@ -159,7 +165,6 @@ export class MarqueeView extends React.Component panx: 0, pany: 0, borderRounding: e.key === "e" ? -1 : undefined, - backgroundColor: selected.length ? "white" : "", scale: zoomBasis, width: bounds.width * zoomBasis, height: bounds.height * zoomBasis, @@ -178,9 +183,10 @@ export class MarqueeView extends React.Component else { this.props.addDocument(newCollection, false); } - this.cleanupInteractions(true); + this.cleanupInteractions(false); } if (e.key === "s") { + this._commandExecuted = true; e.stopPropagation(); e.preventDefault(); let bounds = this.Bounds; @@ -190,7 +196,7 @@ export class MarqueeView extends React.Component this.props.addLiveTextDocument(summary); selected.map(select => summary.GetPrototype()!.CreateLink(select.GetPrototype()!)); - this.cleanupInteractions(true); + this.cleanupInteractions(false); } } @action -- cgit v1.2.3-70-g09d2 From 36fd1b6b6c1ba02be08609176ed7c3e5d0e7f4c4 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 27 Apr 2019 09:17:13 -0400 Subject: fixed marquee and doc decorations bugs --- src/client/views/collections/CollectionBaseView.tsx | 2 ++ src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 6 ++++-- 2 files changed, 6 insertions(+), 2 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 6cb650770..aa8fce923 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -8,6 +8,7 @@ import { ListField } from '../../../fields/ListField'; import { NumberField } from '../../../fields/NumberField'; import { ContextMenu } from '../ContextMenu'; import { FieldViewProps } from '../nodes/FieldView'; +import { SelectionManager } from '../../util/SelectionManager'; export enum CollectionViewType { Invalid, @@ -173,6 +174,7 @@ 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/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 89308d573..da1170759 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -78,7 +78,9 @@ export class MarqueeView extends React.Component if (!e.cancelBubble) { if (Math.abs(this._lastX - this._downX) > Utils.DRAG_THRESHOLD || Math.abs(this._lastY - this._downY) > Utils.DRAG_THRESHOLD) { - this._visible = true; + if (!this._commandExecuted) { + this._visible = true; + } e.stopPropagation(); e.preventDefault(); } @@ -173,7 +175,7 @@ export class MarqueeView extends React.Component }); this.marqueeInkDelete(inkData); - SelectionManager.DeselectAll(); + // SelectionManager.DeselectAll(); if (e.key === "r") { let summary = Documents.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, backgroundColor: "yellow", title: "-summary-" }); summary.GetPrototype()!.CreateLink(newCollection.GetPrototype()!); -- cgit v1.2.3-70-g09d2 From d4a77dd055685dd81a762ef40e0c3b7606586e9c Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sat, 27 Apr 2019 21:40:17 -0400 Subject: Split more files up --- src/client/DocServer.ts | 3 +- src/client/northstar/dash-fields/HistogramField.ts | 2 +- src/client/northstar/dash-nodes/HistogramBox.tsx | 3 +- src/client/util/Scripting.ts | 1 + src/client/views/Main.tsx | 3 +- .../views/collections/CollectionBaseView.tsx | 3 +- .../views/collections/CollectionDockingView.tsx | 3 +- .../views/collections/CollectionSchemaView.tsx | 3 +- src/client/views/collections/CollectionSubView.tsx | 3 +- .../views/collections/CollectionTreeView.tsx | 3 +- .../CollectionFreeFormLinksView.tsx | 3 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 3 +- src/client/views/nodes/DocumentView.tsx | 3 +- src/client/views/nodes/FieldView.tsx | 1 + src/client/views/nodes/LinkMenu.tsx | 3 +- src/new_fields/Doc.ts | 37 +++------------------- src/new_fields/HtmlField.ts | 2 +- src/new_fields/IconField.ts | 2 +- src/new_fields/InkField.ts | 2 +- src/new_fields/List.ts | 3 +- src/new_fields/ObjectField.ts | 17 ++++++++++ src/new_fields/Proxy.ts | 4 ++- src/new_fields/RefField.ts | 18 +++++++++++ src/new_fields/RichTextField.ts | 2 +- src/new_fields/Schema.ts | 8 ++--- src/new_fields/Types.ts | 2 +- src/new_fields/URLField.ts | 2 +- src/new_fields/util.ts | 4 ++- .../authentication/controllers/WorkspacesMenu.tsx | 3 +- src/server/database.ts | 2 ++ 30 files changed, 88 insertions(+), 60 deletions(-) create mode 100644 src/new_fields/ObjectField.ts create mode 100644 src/new_fields/RefField.ts (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index 3f17baec6..c7cbfce37 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -1,8 +1,9 @@ import * as OpenSocket from 'socket.io-client'; import { MessageStore, Types, Message } from "./../server/Message"; -import { Opt, FieldWaiting, RefField, HandleUpdate } from '../new_fields/Doc'; +import { Opt, FieldWaiting } from '../new_fields/Doc'; import { Utils } from '../Utils'; import { SerializationHelper } from './util/SerializationHelper'; +import { RefField, HandleUpdate } from '../new_fields/RefField'; 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 118f4cf7f..730289536 100644 --- a/src/client/northstar/dash-fields/HistogramField.ts +++ b/src/client/northstar/dash-fields/HistogramField.ts @@ -3,7 +3,7 @@ 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 } from "../../../new_fields/Doc"; +import { ObjectField } from "../../../new_fields/ObjectField"; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; import { OmitKeys } from "../../../Utils"; import { Deserializable } from "../../util/SerializationHelper"; diff --git a/src/client/northstar/dash-nodes/HistogramBox.tsx b/src/client/northstar/dash-nodes/HistogramBox.tsx index 4a65b14cf..a9c68ccba 100644 --- a/src/client/northstar/dash-nodes/HistogramBox.tsx +++ b/src/client/northstar/dash-nodes/HistogramBox.tsx @@ -20,7 +20,8 @@ import { HistogramLabelPrimitives } from "./HistogramLabelPrimitives"; import { StyleConstants } from "../utils/StyleContants"; import { NumCast, Cast } from "../../../new_fields/Types"; import { listSpec } from "../../../new_fields/Schema"; -import { Doc, Id } from "../../../new_fields/Doc"; +import { Doc } from "../../../new_fields/Doc"; +import { Id } from "../../../new_fields/RefField"; @observer diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index dbec82340..e45f61c11 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -11,6 +11,7 @@ import { Docs } from "../documents/Documents"; import { Doc, Field } from '../../new_fields/Doc'; import { ImageField, PdfField, VideoField, AudioField } from '../../new_fields/URLField'; import { List } from '../../new_fields/List'; +import { RichTextField } from '../../new_fields/RichTextField'; export interface ScriptSucccess { success: true; diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 1e3d4e259..4a68d1c68 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -33,10 +33,11 @@ import { MainOverlayTextBox } from './MainOverlayTextBox'; import { DocumentView } from './nodes/DocumentView'; import { PreviewCursor } from './PreviewCursor'; import { SelectionManager } from '../util/SelectionManager'; -import { FieldResult, Field, Doc, Id, Opt } from '../../new_fields/Doc'; +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'; @observer diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index 4807dc40a..b2fba1415 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -4,9 +4,10 @@ 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, Id } from '../../../new_fields/Doc'; +import { Doc, FieldResult, Opt } from '../../../new_fields/Doc'; import { listSpec } from '../../../new_fields/Schema'; import { List } from '../../../new_fields/List'; +import { Id } from '../../../new_fields/RefField'; export enum CollectionViewType { Invalid, diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 2ff409b9b..1574562c6 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -13,11 +13,12 @@ import React = require("react"); import { SubCollectionViewProps } from "./CollectionSubView"; import { DragManager, DragLinksAsDocuments } from "../../util/DragManager"; import { Transform } from '../../util/Transform'; -import { Doc, Id, Opt, Field, FieldId } from "../../../new_fields/Doc"; +import { Doc, Opt, Field } from "../../../new_fields/Doc"; import { Cast, NumCast } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; import { DocServer } from "../../DocServer"; import { listSpec } from "../../../new_fields/Schema"; +import { Id, FieldId } from "../../../new_fields/RefField"; @observer export class CollectionDockingView extends React.Component { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 874170f3d..58d20819b 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -19,10 +19,11 @@ import { DocumentView } from "../nodes/DocumentView"; import { FieldView, FieldViewProps } from "../nodes/FieldView"; import "./CollectionSchemaView.scss"; import { CollectionSubView } from "./CollectionSubView"; -import { Opt, Field, Doc, Id } from "../../../new_fields/Doc"; +import { Opt, Field, Doc } from "../../../new_fields/Doc"; import { Cast, FieldValue, NumCast } from "../../../new_fields/Types"; import { listSpec } from "../../../new_fields/Schema"; import { List } from "../../../new_fields/List"; +import { Id } from "../../../new_fields/RefField"; // bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 558a8728f..4d090b680 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -10,12 +10,13 @@ import * as rp from 'request-promise'; import { CollectionView } from "./CollectionView"; import { CollectionPDFView } from "./CollectionPDFView"; import { CollectionVideoView } from "./CollectionVideoView"; -import { Doc, ObjectField, Opt } from "../../../new_fields/Doc"; +import { Doc, Opt } from "../../../new_fields/Doc"; import { DocComponent } from "../DocComponent"; import { listSpec } from "../../../new_fields/Schema"; import { Cast, PromiseValue } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; import { DocServer } from "../../DocServer"; +import { ObjectField } from "../../../new_fields/ObjectField"; 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 c9d8d83c8..7ec9a8549 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -10,7 +10,8 @@ import "./CollectionTreeView.scss"; import React = require("react"); import { Document, listSpec } from '../../../new_fields/Schema'; import { Cast, StrCast, BoolCast } from '../../../new_fields/Types'; -import { Doc, Id } from '../../../new_fields/Doc'; +import { Doc } from '../../../new_fields/Doc'; +import { Id } from '../../../new_fields/RefField'; export interface TreeViewProps { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx index ce9995630..f693d55e8 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx @@ -7,10 +7,11 @@ import { CollectionViewProps } from "../CollectionSubView"; import "./CollectionFreeFormLinksView.scss"; import { CollectionFreeFormLinkView } from "./CollectionFreeFormLinkView"; import React = require("react"); -import { Doc, Id } from "../../../../new_fields/Doc"; +import { Doc } 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"; @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 047fbad18..18107e98a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -19,10 +19,11 @@ import { MarqueeView } from "./MarqueeView"; import React = require("react"); import v5 = require("uuid/v5"); import { createSchema, makeInterface, listSpec } from "../../../../new_fields/Schema"; -import { Doc, Id } from "../../../../new_fields/Doc"; +import { Doc } from "../../../../new_fields/Doc"; import { FieldValue, Cast, NumCast } from "../../../../new_fields/Types"; import { pageSchema } from "../../nodes/ImageBox"; import { List } from "../../../../new_fields/List"; +import { Id } from "../../../../new_fields/RefField"; export const panZoomSchema = createSchema({ panX: "number", diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index aabc1633e..c304b6a35 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -15,7 +15,7 @@ import { ContextMenu } from "../ContextMenu"; import { DocumentContentsView } from "./DocumentContentsView"; import "./DocumentView.scss"; import React = require("react"); -import { Field, Opt, Doc, Id } from "../../../new_fields/Doc"; +import { Opt, Doc } from "../../../new_fields/Doc"; import { DocComponent } from "../DocComponent"; import { createSchema, makeInterface, listSpec } from "../../../new_fields/Schema"; import { FieldValue, Cast, PromiseValue } from "../../../new_fields/Types"; @@ -24,6 +24,7 @@ import { CollectionFreeFormView } from "../collections/collectionFreeForm/Collec import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; import { MarqueeView } from "../collections/collectionFreeForm/MarqueeView"; import { DocServer } from "../../DocServer"; +import { Id } from "../../../new_fields/RefField"; const linkSchema = createSchema({ title: "string", diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index c00c47fc4..dc36c5914 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -16,6 +16,7 @@ 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"; // diff --git a/src/client/views/nodes/LinkMenu.tsx b/src/client/views/nodes/LinkMenu.tsx index 3ecc8555d..e21adebbc 100644 --- a/src/client/views/nodes/LinkMenu.tsx +++ b/src/client/views/nodes/LinkMenu.tsx @@ -5,9 +5,10 @@ import { LinkBox } from "./LinkBox"; import { LinkEditor } from "./LinkEditor"; import './LinkMenu.scss'; import React = require("react"); -import { Doc, Id } from "../../../new_fields/Doc"; +import { Doc } from "../../../new_fields/Doc"; import { Cast, FieldValue } from "../../../new_fields/Types"; import { listSpec } from "../../../new_fields/Schema"; +import { Id } from "../../../new_fields/RefField"; interface Props { docView: DocumentView; diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index fb7b6e360..4ef2a465f 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -8,38 +8,8 @@ import { Cast, ToConstructor, PromiseValue, FieldValue } from "./Types"; import { UndoManager, undoBatch } from "../client/util/UndoManager"; import { listSpec } from "./Schema"; import { List } from "./List"; - -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; - readonly [Id]: FieldId; - - constructor(id?: FieldId) { - this.__id = id || Utils.GenerateGuid(); - this[Id] = this.__id; - } - - protected [HandleUpdate]?(diff: any): void; -} - -export const Update = Symbol("Update"); -export const OnUpdate = Symbol("OnUpdate"); -export const Parent = Symbol("Parent"); -export class ObjectField { - protected [OnUpdate]?: (diff?: any) => void; - private [Parent]?: Doc; - readonly [Id] = ""; -} - -export namespace ObjectField { - export function MakeCopy(field: ObjectField) { - //TODO Types - return field; - } -} +import { ObjectField } from "./ObjectField"; +import { RefField, FieldId, Id } from "./RefField"; export function IsField(field: any): field is Field { return (typeof field === "string") @@ -53,6 +23,7 @@ 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"); @Deserializable("doc").withFields(["id"]) @@ -161,7 +132,7 @@ export namespace Doc { copy[key] = field; } } - }) + }); return copy; } diff --git a/src/new_fields/HtmlField.ts b/src/new_fields/HtmlField.ts index 76fdb1f62..808a3499b 100644 --- a/src/new_fields/HtmlField.ts +++ b/src/new_fields/HtmlField.ts @@ -1,6 +1,6 @@ import { Deserializable } from "../client/util/SerializationHelper"; import { serializable, primitive } from "serializr"; -import { ObjectField } from "./Doc"; +import { ObjectField } from "./ObjectField"; @Deserializable("html") export class HtmlField extends ObjectField { diff --git a/src/new_fields/IconField.ts b/src/new_fields/IconField.ts index 32f3aa4d5..46f111f8e 100644 --- a/src/new_fields/IconField.ts +++ b/src/new_fields/IconField.ts @@ -1,6 +1,6 @@ import { Deserializable } from "../client/util/SerializationHelper"; import { serializable, primitive } from "serializr"; -import { ObjectField } from "./Doc"; +import { ObjectField } from "./ObjectField"; @Deserializable("icon") export class IconField extends ObjectField { diff --git a/src/new_fields/InkField.ts b/src/new_fields/InkField.ts index 49e6bf61e..42223c494 100644 --- a/src/new_fields/InkField.ts +++ b/src/new_fields/InkField.ts @@ -1,6 +1,6 @@ import { Deserializable } from "../client/util/SerializationHelper"; import { serializable, custom, createSimpleSchema, list, object, map } from "serializr"; -import { ObjectField } from "./Doc"; +import { ObjectField } from "./ObjectField"; export enum InkTool { None, diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts index f01ac210a..428f661c9 100644 --- a/src/new_fields/List.ts +++ b/src/new_fields/List.ts @@ -1,8 +1,9 @@ import { Deserializable, autoObject } from "../client/util/SerializationHelper"; -import { Field, ObjectField, Update, OnUpdate, Self } from "./Doc"; +import { Field, Update, Self } from "./Doc"; import { setter, getter } from "./util"; import { serializable, alias, list } from "serializr"; import { observable } from "mobx"; +import { ObjectField, OnUpdate } from "./ObjectField"; @Deserializable("list") class ListImpl extends ObjectField { diff --git a/src/new_fields/ObjectField.ts b/src/new_fields/ObjectField.ts new file mode 100644 index 000000000..9cac2c528 --- /dev/null +++ b/src/new_fields/ObjectField.ts @@ -0,0 +1,17 @@ +import { Doc } from "./Doc"; + +export const OnUpdate = Symbol("OnUpdate"); +export const Parent = Symbol("Parent"); +const Id = Symbol("Object Id"); +export class ObjectField { + protected [OnUpdate]?: (diff?: any) => void; + private [Parent]?: Doc; + readonly [Id] = ""; +} + +export namespace ObjectField { + export function MakeCopy(field: ObjectField) { + //TODO Types + return field; + } +} diff --git a/src/new_fields/Proxy.ts b/src/new_fields/Proxy.ts index 2aa78731e..56e41cc0f 100644 --- a/src/new_fields/Proxy.ts +++ b/src/new_fields/Proxy.ts @@ -1,8 +1,10 @@ import { Deserializable } from "../client/util/SerializationHelper"; -import { RefField, Id, ObjectField, FieldWaiting } from "./Doc"; +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 } from "./ObjectField"; @Deserializable("proxy") export class ProxyField extends ObjectField { diff --git a/src/new_fields/RefField.ts b/src/new_fields/RefField.ts new file mode 100644 index 000000000..202c65f21 --- /dev/null +++ b/src/new_fields/RefField.ts @@ -0,0 +1,18 @@ +import { serializable, primitive, alias } from "serializr"; +import { Utils } from "../Utils"; + +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; + readonly [Id]: FieldId; + + constructor(id?: FieldId) { + this.__id = id || Utils.GenerateGuid(); + this[Id] = this.__id; + } + + protected [HandleUpdate]?(diff: any): void; +} diff --git a/src/new_fields/RichTextField.ts b/src/new_fields/RichTextField.ts index 156e4efd9..0fa3cf73c 100644 --- a/src/new_fields/RichTextField.ts +++ b/src/new_fields/RichTextField.ts @@ -1,4 +1,4 @@ -import { ObjectField } from "./Doc"; +import { ObjectField } from "./ObjectField"; import { serializable } from "serializr"; export class RichTextField extends ObjectField { diff --git a/src/new_fields/Schema.ts b/src/new_fields/Schema.ts index 5081521c7..7444878fe 100644 --- a/src/new_fields/Schema.ts +++ b/src/new_fields/Schema.ts @@ -21,15 +21,15 @@ export function makeInterface(...schemas: T): (doc?: Doc) } } const proto = new Proxy({}, { - get(target: any, prop) { - const field = target.doc[prop]; + get(target: any, prop, receiver) { + const field = receiver.doc[prop]; if (prop in schema) { return Cast(field, (schema as any)[prop]); } return field; }, - set(target: any, prop, value) { - target.doc[prop] = value; + set(target: any, prop, value, receiver) { + receiver.doc[prop] = value; return true; } }); diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts index 7fa18673f..3f8eabd45 100644 --- a/src/new_fields/Types.ts +++ b/src/new_fields/Types.ts @@ -1,4 +1,4 @@ -import { Field, Opt, FieldWaiting, FieldResult, RefField } from "./Doc"; +import { Field, Opt, FieldResult } from "./Doc"; import { List } from "./List"; export type ToType | ListSpec> = diff --git a/src/new_fields/URLField.ts b/src/new_fields/URLField.ts index 1da245e73..95c679df7 100644 --- a/src/new_fields/URLField.ts +++ b/src/new_fields/URLField.ts @@ -1,6 +1,6 @@ import { Deserializable } from "../client/util/SerializationHelper"; import { serializable, custom } from "serializr"; -import { ObjectField } from "./Doc"; +import { ObjectField } from "./ObjectField"; function url() { return custom( diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts index 2d9721b2e..011e8c8d9 100644 --- a/src/new_fields/util.ts +++ b/src/new_fields/util.ts @@ -1,8 +1,10 @@ import { UndoManager } from "../client/util/UndoManager"; -import { Update, OnUpdate, Parent, ObjectField, RefField, Doc, Id, Field } from "./Doc"; +import { Update, 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"; export function setter(target: any, prop: string | symbol | number, value: any, receiver: any): boolean { if (SerializationHelper.IsSerializing()) { diff --git a/src/server/authentication/controllers/WorkspacesMenu.tsx b/src/server/authentication/controllers/WorkspacesMenu.tsx index 29327e5ad..91756315d 100644 --- a/src/server/authentication/controllers/WorkspacesMenu.tsx +++ b/src/server/authentication/controllers/WorkspacesMenu.tsx @@ -3,8 +3,9 @@ import { observable, action, configure, reaction, computed, ObservableMap, runIn import { observer } from "mobx-react"; import './WorkspacesMenu.css'; import { EditableView } from '../../../client/views/EditableView'; -import { Doc, Id } from '../../../new_fields/Doc'; +import { Doc } from '../../../new_fields/Doc'; import { StrCast } from '../../../new_fields/Types'; +import { Id } from '../../../new_fields/RefField'; export interface WorkspaceMenuProps { active: Doc | undefined; diff --git a/src/server/database.ts b/src/server/database.ts index a61b4d823..6b3b6797f 100644 --- a/src/server/database.ts +++ b/src/server/database.ts @@ -60,11 +60,13 @@ export class Database { } public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = Database.DocumentsCollection) { + console.log("getDocument"); this.db && this.db.collection(collectionName).findOne({ id: id }, (err, result) => fn(result ? ({ id: result._id, type: result.type, data: result.data }) : undefined)); } public getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = Database.DocumentsCollection) { + console.log("getDocuments"); this.db && this.db.collection(collectionName).find({ id: { "$in": ids } }).toArray((err, docs) => { if (err) { console.log(err.message); -- cgit v1.2.3-70-g09d2 From a2751d16babb38cde2b86b1cb8fc5d74c15762d7 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sun, 28 Apr 2019 00:23:18 -0400 Subject: Decent amount of stuff is working --- src/client/views/Main.tsx | 2 +- src/client/views/collections/CollectionBaseView.tsx | 2 +- src/client/views/collections/CollectionPDFView.tsx | 3 ++- src/client/views/collections/CollectionVideoView.tsx | 3 ++- src/client/views/collections/CollectionView.tsx | 3 ++- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 1 + src/client/views/nodes/DocumentView.tsx | 4 ++-- src/client/views/nodes/FormattedTextBox.tsx | 3 ++- src/client/views/nodes/PDFBox.tsx | 2 +- src/new_fields/RichTextField.ts | 2 ++ src/new_fields/Types.ts | 2 +- 12 files changed, 18 insertions(+), 11 deletions(-) (limited to 'src/client/views/collections/CollectionBaseView.tsx') diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 4a68d1c68..98c5a5306 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -165,7 +165,7 @@ export class Main extends React.Component { @action openWorkspace = async (doc: Doc, fromHistory = false) => { this.mainContainer = doc; - fromHistory || window.history.pushState(null, StrCast(doc.title), "/doc/" + doc.Id); + fromHistory || window.history.pushState(null, StrCast(doc.title), "/doc/" + doc[Id]); const col = await Cast(CurrentUserUtils.UserDocument.optionalRightCollection, Doc); // if there is a pending doc, and it has new data, show it (syip: we use a timeout to prevent collection docking view from being uninitialized) setTimeout(async () => { diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx index b2fba1415..ed761d3f3 100644 --- a/src/client/views/collections/CollectionBaseView.tsx +++ b/src/client/views/collections/CollectionBaseView.tsx @@ -95,7 +95,7 @@ export class CollectionBaseView extends React.Component { //TODO This won't create the field if it doesn't already exist const value = Cast(props.Document[props.fieldKey], listSpec(Doc)); if (value !== undefined) { - if (allowDuplicates || !value.some(v => v.Id === doc.Id)) { + if (allowDuplicates || !value.some(v => v[Id] === doc[Id])) { value.push(doc); } } else { diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx index 99438b4e8..5a1af354a 100644 --- a/src/client/views/collections/CollectionPDFView.tsx +++ b/src/client/views/collections/CollectionPDFView.tsx @@ -8,6 +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"; @observer @@ -33,7 +34,7 @@ export class CollectionPDFView extends React.Component { } onContextMenu = (e: React.MouseEvent): void => { - if (!e.isPropagationStopped() && this.props.Document.Id !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 + 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: "PDFOptions", event: emptyFunction }); } } diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx index d45be228a..7232ecea2 100644 --- a/src/client/views/collections/CollectionVideoView.tsx +++ b/src/client/views/collections/CollectionVideoView.tsx @@ -8,6 +8,7 @@ import { CollectionFreeFormView } from "./collectionFreeForm/CollectionFreeFormV import { FieldView, FieldViewProps } from "../nodes/FieldView"; import { emptyFunction } from "../../../Utils"; import { NumCast } from "../../../new_fields/Types"; +import { Id } from "../../../new_fields/RefField"; @observer @@ -107,7 +108,7 @@ export class CollectionVideoView extends React.Component { } onContextMenu = (e: React.MouseEvent): void => { - if (!e.isPropagationStopped() && this.props.Document.Id !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 + 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: "VideoOptions", event: emptyFunction }); } } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index b72065bca..c2049a09a 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -10,6 +10,7 @@ import { CurrentUserUtils } from '../../../server/authentication/models/current_ import { observer } from 'mobx-react'; import { undoBatch } from '../../util/UndoManager'; import { trace } from 'mobx'; +import { Id } from '../../../new_fields/RefField'; @observer export class CollectionView extends React.Component { @@ -31,7 +32,7 @@ export class CollectionView extends React.Component { get isAnnotationOverlay() { return this.props.fieldKey && this.props.fieldKey === "annotations"; } // bcz: ? Why do we need to compare Id's? 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 + 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) }); ContextMenu.Instance.addItem({ description: "Schema", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Schema) }); ContextMenu.Instance.addItem({ description: "Treeview", event: undoBatch(() => this.props.Document.viewType = CollectionViewType.Tree) }); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index dfacca204..dcded7648 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -257,7 +257,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { moveDocument: this.props.moveDocument, ScreenToLocalTransform: this.getTransform, isTopMost: false, - selectOnLoad: document.Id === this._selectOnLoaded, + selectOnLoad: document[Id] === this._selectOnLoaded, PanelWidth: () => Cast(document.width, "number", 0),//TODO Types These are inline functions PanelHeight: () => Cast(document.height, "number", 0), ContentScaling: returnOne, diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 376af0b36..8766eb7ea 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -20,6 +20,7 @@ const schema = createSchema({ zIndex: "number" }); +//TODO Types: The import order is wrong, so positionSchema is undefined type FreeformDocument = makeInterface<[typeof schema, typeof positionSchema]>; const FreeformDocument = makeInterface(schema, positionSchema); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index c304b6a35..3814eeb9c 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -139,7 +139,7 @@ export class DocumentView extends DocComponent(Docu } onClick = (e: React.MouseEvent): void => { - if (CurrentUserUtils.MainDocId !== this.props.Document.Id && + 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); @@ -247,7 +247,7 @@ export class DocumentView extends DocComponent(Docu ContextMenu.Instance.addItem({ description: "Fields", event: this.fieldsClicked }); ContextMenu.Instance.addItem({ description: "Center", event: () => this.props.focus(this.props.Document) }); ContextMenu.Instance.addItem({ description: "Open Right", event: () => CollectionDockingView.Instance.AddRightSplit(this.props.Document) }); - ContextMenu.Instance.addItem({ description: "Copy URL", event: () => Utils.CopyText(DocServer.prepend("/doc/" + this.props.Document.Id)) }); + ContextMenu.Instance.addItem({ description: "Copy URL", event: () => Utils.CopyText(DocServer.prepend("/doc/" + this.props.Document[Id])) }); ContextMenu.Instance.addItem({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]) }); //ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) }) ContextMenu.Instance.addItem({ description: "Delete", event: this.deleteClicked }); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 96512718f..c4c720ca9 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -22,6 +22,7 @@ import { observer } from "mobx-react"; import { InkingControl } from "../InkingControl"; import { StrCast, Cast } from "../../../new_fields/Types"; import { RichTextField } from "../../../new_fields/RichTextField"; +import { Id } from "../../../new_fields/RefField"; const { buildMenuItems } = require("prosemirror-example-setup"); const { menuBar } = require("prosemirror-menu"); @@ -108,7 +109,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe }; if (this.props.isOverlay) { - this._inputReactionDisposer = reaction(() => MainOverlayTextBox.Instance.TextDoc && MainOverlayTextBox.Instance.TextDoc.Id, + this._inputReactionDisposer = reaction(() => MainOverlayTextBox.Instance.TextDoc && MainOverlayTextBox.Instance.TextDoc[Id], () => { if (this._editorView) { this._editorView.destroy(); diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 7fbfed1c0..9f0849492 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -447,7 +447,7 @@ export class PDFBox extends DocComponent(PdfDocumen let pdfUrl = Cast(this.props.Document[this.props.fieldKey], PdfField); let xf = FieldValue(this.Document.nativeHeight, 0) / renderHeight; return
- + {({ measureRef }) =>
diff --git a/src/new_fields/RichTextField.ts b/src/new_fields/RichTextField.ts index 0fa3cf73c..f2033d5a7 100644 --- a/src/new_fields/RichTextField.ts +++ b/src/new_fields/RichTextField.ts @@ -1,6 +1,8 @@ import { ObjectField } from "./ObjectField"; import { serializable } from "serializr"; +import { Deserializable } from "../client/util/SerializationHelper"; +@Deserializable("RichTextField") export class RichTextField extends ObjectField { @serializable(true) readonly Data: string; diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts index 3f8eabd45..e179c2602 100644 --- a/src/new_fields/Types.ts +++ b/src/new_fields/Types.ts @@ -76,7 +76,7 @@ type WithoutList = T extends List ? R[] : T; export function FieldValue>(field: FieldResult, defaultValue: U): WithoutList; export function FieldValue(field: FieldResult): Opt; export function FieldValue(field: FieldResult, defaultValue?: T): Opt { - return field instanceof Promise ? defaultValue : field; + return (field instanceof Promise || field === undefined) ? defaultValue : field; } export interface PromiseLike { -- cgit v1.2.3-70-g09d2