From 49310acbdfd7ca239c939208b3766c54e980f6f1 Mon Sep 17 00:00:00 2001 From: ab Date: Sat, 6 Apr 2019 18:43:15 -0400 Subject: drop fraught but technically undoable --- src/client/util/TooltipTextMenu.tsx | 2 +- src/client/util/UndoManager.ts | 23 +++++++-- src/client/views/InkingCanvas.tsx | 14 +++-- src/client/views/InkingControl.tsx | 3 +- .../views/collections/CollectionDockingView.tsx | 1 + src/client/views/collections/CollectionView.tsx | 7 +-- .../views/collections/CollectionViewBase.tsx | 60 +++++++++++++--------- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/PDFBox.tsx | 4 +- 9 files changed, 76 insertions(+), 40 deletions(-) (limited to 'src/client') diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 2a613ba8b..3a6eadac0 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -49,7 +49,7 @@ export class TooltipTextMenu { e.preventDefault(); view.focus(); items.forEach(({ command, dom }) => { - if (dom.contains(e.srcElement)) { + if (e.srcElement && dom.contains(e.srcElement as Node)) { let active = command(view.state, view.dispatch, view); //uncomment this if we want the bullet button to disappear if current selection is bulleted // dom.style.display = active ? "" : "none" diff --git a/src/client/util/UndoManager.ts b/src/client/util/UndoManager.ts index 6d1b2f1b8..92a6c14e2 100644 --- a/src/client/util/UndoManager.ts +++ b/src/client/util/UndoManager.ts @@ -34,7 +34,20 @@ function propertyDecorator(target: any, key: string | symbol) { } }) } -export function undoBatch(target: any, key: string | symbol, descriptor?: TypedPropertyDescriptor): any { + +export function undoBatch(target: any, key: string | symbol, descriptor?: TypedPropertyDescriptor): any; +export function undoBatch(fn: (...args: any[]) => any): (...args: any[]) => any; +export function undoBatch(target: any, key?: string | symbol, descriptor?: TypedPropertyDescriptor): any { + if (!key) { + return function () { + let batch = UndoManager.StartBatch(""); + try { + return target.apply(undefined, arguments) + } finally { + batch.end(); + } + } + } if (!descriptor) { propertyDecorator(target, key); return; @@ -84,6 +97,7 @@ export namespace UndoManager { export function GetOpenBatches(): Without[] { return openBatches; } + export class Batch { private disposed: boolean = false; @@ -125,8 +139,11 @@ export namespace UndoManager { export function RunInBatch(fn: () => void, batchName: string) { let batch = StartBatch(batchName); - fn(); - batch.end(); + try { + fn(); + } finally { + batch.end(); + } } export const Undo = action(() => { diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx index 123ff679b..f7a3601bc 100644 --- a/src/client/views/InkingCanvas.tsx +++ b/src/client/views/InkingCanvas.tsx @@ -10,6 +10,7 @@ import "./InkingCanvas.scss"; import { InkingControl } from "./InkingControl"; import { InkingStroke } from "./InkingStroke"; import React = require("react"); +import { undoBatch } from "../util/UndoManager"; interface InkCanvasProps { getScreenTransform: () => Transform; @@ -21,10 +22,13 @@ export class InkingCanvas extends React.Component { static InkOffset: number = 50000; private _currentStrokeId: string = ""; public static IntersectStrokeRect(stroke: StrokeData, selRect: { left: number, top: number, width: number, height: number }): boolean { - return stroke.pathData.reduce((inside, val) => inside || - (selRect.left < val.x - InkingCanvas.InkOffset && selRect.left + selRect.width > val.x - InkingCanvas.InkOffset && - selRect.top < val.y - InkingCanvas.InkOffset && selRect.top + selRect.height > val.y - InkingCanvas.InkOffset) - , false); + return stroke.pathData.reduce((inside: boolean, val) => inside || + ( + selRect.left < val.x - InkingCanvas.InkOffset && + selRect.left + selRect.width > val.x - InkingCanvas.InkOffset && + selRect.top < val.y - InkingCanvas.InkOffset && + selRect.top + selRect.height > val.y - InkingCanvas.InkOffset + ), false); } @computed @@ -83,7 +87,7 @@ export class InkingCanvas extends React.Component { } this.inkData = data; } - } + }; relativeCoordinatesForEvent = (ex: number, ey: number): { x: number, y: number } => { let [x, y] = this.props.getScreenTransform().transformPoint(ex, ey); diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx index c1519dff8..dcaf472ca 100644 --- a/src/client/views/InkingControl.tsx +++ b/src/client/views/InkingControl.tsx @@ -21,7 +21,7 @@ export class InkingControl extends React.Component { @observable private _selectedColor: string = "rgb(244, 67, 54)"; @observable private _selectedWidth: string = "25"; @observable private _open: boolean = false; - @observable private _colorPickerDisplay: boolean = false; + @observable private _colorPickerDisplay = false; constructor(props: Readonly<{}>) { super(props); @@ -76,6 +76,7 @@ export class InkingControl extends React.Component { this._open = !this._open; } + @action toggleColorPicker = () => { this._colorPickerDisplay = !this._colorPickerDisplay; diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 39e0dd989..4d9985db3 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -226,6 +226,7 @@ export class CollectionDockingView extends React.Component { this.stateChanged(); } + tabCreated = (tab: any) => { if (tab.hasOwnProperty("contentItem") && tab.contentItem.config.type != "stack") { if (tab.titleElement[0].textContent.indexOf("-waiting") != -1) { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 014aa1d8f..42ed3c86b 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -14,6 +14,7 @@ import { CollectionViewProps } from "./CollectionViewBase"; import { CollectionTreeView } from "./CollectionTreeView"; import { Field, FieldId, FieldWaiting } from "../../../fields/Field"; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; +import { undoBatch } from "../../util/UndoManager"; export enum CollectionViewType { Invalid, @@ -134,9 +135,9 @@ export class CollectionView extends React.Component { specificContextMenu = (e: React.MouseEvent): void => { if (!e.isPropagationStopped() && this.props.Document.Id != CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 - ContextMenu.Instance.addItem({ description: "Freeform", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform) }) - ContextMenu.Instance.addItem({ description: "Schema", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Schema) }) - ContextMenu.Instance.addItem({ description: "Treeview", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Tree) }) + ContextMenu.Instance.addItem({ description: "Freeform", event: undoBatch(() => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform)) }) + ContextMenu.Instance.addItem({ description: "Schema", event: undoBatch(() => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Schema)) }) + ContextMenu.Instance.addItem({ description: "Treeview", event: undoBatch(() => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Tree)) }) } } diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index 316d20c9d..2042b2712 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -4,7 +4,7 @@ import { ListField } from "../../../fields/ListField"; import React = require("react"); import { KeyStore } from "../../../fields/KeyStore"; import { FieldWaiting, Opt } from "../../../fields/Field"; -import { undoBatch } from "../../util/UndoManager"; +import { undoBatch, UndoManager } from "../../util/UndoManager"; import { DragManager } from "../../util/DragManager"; import { Documents, DocumentOptions } from "../../documents/Documents"; import { Key } from "../../../fields/Key"; @@ -14,9 +14,10 @@ import { RouteStore } from "../../../server/RouteStore"; import { TupleField } from "../../../fields/TupleField"; import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils"; import { NumberField } from "../../../fields/NumberField"; -import request = require("request"); +import * as rp from "request-promise"; import { ServerUtils } from "../../../server/ServerUtil"; import { Server } from "../../Server"; +import { emptyStatement } from "babel-types"; export interface CollectionViewProps { fieldKey: Key; @@ -130,6 +131,7 @@ export class CollectionViewBase extends React.Component return ctor ? ctor(path, options) : undefined; } + @undoBatch @action protected onDrop(e: React.DragEvent, options: DocumentOptions): void { let that = this; @@ -151,23 +153,28 @@ export class CollectionViewBase extends React.Component return; } + let batch = UndoManager.StartBatch("collection view drop"); + let promises: Promise[] = []; for (let i = 0; i < e.dataTransfer.items.length; i++) { const upload = window.location.origin + RouteStore.upload; let item = e.dataTransfer.items[i]; if (item.kind === "string" && item.type.indexOf("uri") != -1) { - e.dataTransfer.items[i].getAsString(action((s: string) => { - let document: Document; - request.head(ServerUtils.prepend(RouteStore.corsProxy + "/" + s), (err, res, body) => { + let str: string; + let prom = new Promise(res => + e.dataTransfer.items[i].getAsString(res)).then(action((s: string) => { + str = s; + return rp.head(ServerUtils.prepend(RouteStore.corsProxy + "/" + s)) + })).then(res => { let type = res.headers["content-type"]; if (type) { - let doc = this.getDocumentFromType(type, s, { ...options, width: 300, nativeWidth: 300 }) + let doc = this.getDocumentFromType(type, str, { ...options, width: 300, nativeWidth: 300 }) if (doc) { this.props.addDocument(doc, false); } } }); - // this.props.addDocument(Documents.WebDocument(s, { ...options, width: 300, height: 300 }), false) - })) + promises.push(prom); + // this.props.addDocument(Documents.WebDocument(s, { ...options, width: 300, height: 300 }), false) } let type = item.type if (item.kind == "file") { @@ -178,31 +185,36 @@ export class CollectionViewBase extends React.Component formData.append('file', file) } - fetch(upload, { + let prom = fetch(upload, { method: 'POST', body: formData }).then((res: Response) => { return res.json() }).then(json => { - json.map((file: any) => { + json.map(action((file: any) => { let path = window.location.origin + file - runInAction(() => { - let doc = this.getDocumentFromType(type, path, { ...options, nativeWidth: 300, width: 300 }) - - let docs = that.props.Document.GetT(KeyStore.Data, ListField); - if (docs != FieldWaiting) { - if (!docs) { - docs = new ListField(); - that.props.Document.Set(KeyStore.Data, docs) - } - if (doc) { - docs.Data.push(doc); - } + let doc = this.getDocumentFromType(type, path, { ...options, nativeWidth: 300, width: 300 }) + + let docs = that.props.Document.GetT(KeyStore.Data, ListField); + if (docs != FieldWaiting) { + if (!docs) { + docs = new ListField(); + that.props.Document.Set(KeyStore.Data, docs) + } + if (doc) { + docs.Data.push(doc); } - }) - }) + } + })) }) + promises.push(prom); } } + + if (promises.length) { + Promise.all(promises).catch(() => { }).then(() => batch.end()); + } else { + batch.end(); + } } } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index c5178f69d..2dcf645d0 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -188,7 +188,7 @@ export class CollectionFreeFormView extends CollectionViewBase { onDrop = (e: React.DragEvent): void => { var pt = this.getTransform().transformPoint(e.pageX, e.pageY); super.onDrop(e, { x: pt[0], y: pt[1] }); - } + }; onDragOver = (): void => { } diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 28a1f9757..ba022b007 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -151,7 +151,7 @@ export class PDFBox extends React.Component { */ makeEditableAndHighlight = (colour: string) => { var range, sel = window.getSelection(); - if (sel.rangeCount && sel.getRangeAt) { + if (sel && sel.rangeCount && sel.getRangeAt) { range = sel.getRangeAt(0); } document.designMode = "on"; @@ -159,7 +159,7 @@ export class PDFBox extends React.Component { document.execCommand("HiliteColor", false, colour); } - if (range) { + if (sel && range) { sel.removeAllRanges(); sel.addRange(range); -- cgit v1.2.3-70-g09d2 From 9e4dd13ae2f0061ebea6aa8809a5607b51b9d8c3 Mon Sep 17 00:00:00 2001 From: ab Date: Mon, 8 Apr 2019 18:11:22 -0400 Subject: fixed on drop undo redo bug and implemented undo for inking --- src/client/documents/Documents.ts | 17 ++++++++--------- src/client/views/InkingCanvas.tsx | 21 ++++++++++++++++----- src/server/public/files/.gitignore | 1 + 3 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 src/server/public/files/.gitignore (limited to 'src/client') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1f0744782..340983e11 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -70,7 +70,7 @@ export namespace Documents { textProto = fields[textProtoId] as Document; histoProto = fields[histoProtoId] as Document; collProto = fields[collProtoId] as Document; - imageProto = fields[imageProtoId] as Document; + imageProto = fields[imageProtoId] as Document || CreateImagePrototype(); webProto = fields[webProtoId] as Document; kvpProto = fields[kvpProtoId] as Document; }); @@ -111,15 +111,14 @@ export namespace Documents { return assignOptions(deleg, options); } - function GetImagePrototype(): Document { - if (!imageProto) { - imageProto = setupPrototypeOptions(imageProtoId, "IMAGE_PROTO", CollectionView.LayoutString("AnnotationsKey"), - { x: 0, y: 0, nativeWidth: 300, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }); - imageProto.SetText(KeyStore.BackgroundLayout, ImageBox.LayoutString()); - imageProto.SetNumber(KeyStore.CurPage, 0); - } + function CreateImagePrototype(): Document { + let imageProto = setupPrototypeOptions(imageProtoId, "IMAGE_PROTO", CollectionView.LayoutString("AnnotationsKey"), + { x: 0, y: 0, nativeWidth: 300, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }); + imageProto.SetText(KeyStore.BackgroundLayout, ImageBox.LayoutString()); + imageProto.SetNumber(KeyStore.CurPage, 0); return imageProto; } + function GetHistogramPrototype(): Document { if (!histoProto) { histoProto = setupPrototypeOptions(histoProtoId, "HISTO PROTO", CollectionView.LayoutString("AnnotationsKey"), @@ -175,7 +174,7 @@ export namespace Documents { export function ImageDocument(url: string, options: DocumentOptions = {}) { - return assignToDelegate(SetInstanceOptions(GetImagePrototype(), options, [new URL(url), ImageField]).MakeDelegate(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }); + return assignToDelegate(SetInstanceOptions(imageProto, options, [new URL(url), ImageField]).MakeDelegate(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }); // let doc = SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }, // [new URL(url), ImageField]); // doc.SetText(KeyStore.Caption, "my caption..."); diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx index fed349af3..86566d516 100644 --- a/src/client/views/InkingCanvas.tsx +++ b/src/client/views/InkingCanvas.tsx @@ -20,11 +20,10 @@ interface InkCanvasProps { @observer export class InkingCanvas extends React.Component { - private strokeBatch?: UndoManager.Batch; - maxCanvasDim = 8192 / 2; // 1/2 of the maximum canvas dimension for Chrome @observable inkMidX: number = 0; @observable inkMidY: number = 0; + private previousState?: StrokeMap; private _currentStrokeId: string = ""; public static IntersectStrokeRect(stroke: StrokeData, selRect: { left: number, top: number, width: number, height: number }): boolean { return stroke.pathData.reduce((inside: boolean, val) => inside || @@ -68,18 +67,20 @@ export class InkingCanvas extends React.Component { e.stopPropagation(); e.preventDefault(); + this.previousState = this.inkData; + if (InkingControl.Instance.selectedTool != InkTool.Eraser) { // start the new line, saves a uuid to represent the field of the stroke this._currentStrokeId = Utils.GenerateGuid(); - this.strokeBatch = UndoManager.StartBatch("drawing stroke"); - this.inkData.set(this._currentStrokeId, { + const data = this.inkData; + data.set(this._currentStrokeId, { pathData: [this.relativeCoordinatesForEvent(e.clientX, e.clientY)], color: InkingControl.Instance.selectedColor, width: InkingControl.Instance.selectedWidth, tool: InkingControl.Instance.selectedTool, page: this.props.Document.GetNumber(KeyStore.CurPage, -1) }); - this.strokeBatch.end(); + this.inkData = data; } }; @@ -94,6 +95,16 @@ export class InkingCanvas extends React.Component { } e.stopPropagation(); e.preventDefault(); + + const batch = UndoManager.StartBatch("One ink stroke"); + const oldState = this.previousState || new Map; + this.previousState = undefined; + const newState = this.inkData; + UndoManager.AddEvent({ + undo: () => this.inkData = oldState, + redo: () => this.inkData = newState, + }); + batch.end(); } @action diff --git a/src/server/public/files/.gitignore b/src/server/public/files/.gitignore new file mode 100644 index 000000000..f59ec20aa --- /dev/null +++ b/src/server/public/files/.gitignore @@ -0,0 +1 @@ +* \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 4dd5460cfafc33df30bcccc0145af17f81fe5d3e Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Mon, 8 Apr 2019 21:18:36 -0400 Subject: Changed Documents initialization and fixed key error in main --- src/client/documents/Documents.ts | 115 +++++++++++++++++++------------------- src/client/views/Main.tsx | 8 +-- 2 files changed, 60 insertions(+), 63 deletions(-) (limited to 'src/client') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 46c27e672..c98d6ffc4 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -67,13 +67,16 @@ export namespace Documents { const audioProtoId = "audioProto"; export function initProtos(): Promise { - return Server.GetFields([textProtoId, histoProtoId, collProtoId, imageProtoId, webProtoId, kvpProtoId]).then(fields => { - textProto = fields[textProtoId] as Document; - histoProto = fields[histoProtoId] as Document; - collProto = fields[collProtoId] as Document; + return Server.GetFields([textProtoId, histoProtoId, collProtoId, pdfProtoId, imageProtoId, videoProtoId, audioProtoId, webProtoId, kvpProtoId]).then(fields => { + textProto = fields[textProtoId] as Document || CreateTextPrototype(); + histoProto = fields[histoProtoId] as Document || CreateHistogramPrototype(); + collProto = fields[collProtoId] as Document || CreateCollectionPrototype(); imageProto = fields[imageProtoId] as Document || CreateImagePrototype(); - webProto = fields[webProtoId] as Document; - kvpProto = fields[kvpProtoId] as Document; + webProto = fields[webProtoId] as Document || CreateWebPrototype(); + kvpProto = fields[kvpProtoId] as Document || CreateKVPPrototype(); + videoProto = fields[videoProtoId] as Document || CreateVideoPrototype(); + audioProto = fields[audioProtoId] as Document || CreateAudioPrototype(); + pdfProto = fields[pdfProtoId] as Document || CreatePdfPrototype(); }); } function assignOptions(doc: Document, options: DocumentOptions): Document { @@ -121,57 +124,51 @@ export namespace Documents { return imageProto; } - function GetHistogramPrototype(): Document { - if (!histoProto) { - histoProto = setupPrototypeOptions(histoProtoId, "HISTO PROTO", CollectionView.LayoutString("AnnotationsKey"), - { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }); - histoProto.SetText(KeyStore.BackgroundLayout, HistogramBox.LayoutString()); - } + function CreateHistogramPrototype(): Document { + let histoProto = setupPrototypeOptions(histoProtoId, "HISTO PROTO", CollectionView.LayoutString("AnnotationsKey"), + { x: 0, y: 0, width: 300, height: 300, backgroundColor: "black", layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }); + histoProto.SetText(KeyStore.BackgroundLayout, HistogramBox.LayoutString()); return histoProto; } - function GetTextPrototype(): Document { - return textProto ? textProto : - textProto = setupPrototypeOptions(textProtoId, "TEXT_PROTO", FormattedTextBox.LayoutString(), - { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] }); + function CreateTextPrototype(): Document { + let textProto = setupPrototypeOptions(textProtoId, "TEXT_PROTO", FormattedTextBox.LayoutString(), + { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] }); + return textProto } - function GetPdfPrototype(): Document { - if (!pdfProto) { - pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionPDFView.LayoutString("AnnotationsKey"), - { x: 0, y: 0, nativeWidth: 1200, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] }); - pdfProto.SetNumber(KeyStore.CurPage, 1); - pdfProto.SetText(KeyStore.BackgroundLayout, PDFBox.LayoutString()); - } + function CreatePdfPrototype(): Document { + let pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionPDFView.LayoutString("AnnotationsKey"), + { x: 0, y: 0, nativeWidth: 1200, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] }); + pdfProto.SetNumber(KeyStore.CurPage, 1); + pdfProto.SetText(KeyStore.BackgroundLayout, PDFBox.LayoutString()); return pdfProto; } - function GetWebPrototype(): Document { - return webProto ? webProto : - webProto = setupPrototypeOptions(webProtoId, "WEB_PROTO", WebBox.LayoutString(), - { x: 0, y: 0, width: 300, height: 300, layoutKeys: [KeyStore.Data] }); + function CreateWebPrototype(): Document { + let webProto = setupPrototypeOptions(webProtoId, "WEB_PROTO", WebBox.LayoutString(), + { x: 0, y: 0, width: 300, height: 300, layoutKeys: [KeyStore.Data] }); + return webProto; } - function GetCollectionPrototype(): Document { - return collProto ? collProto : - collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("DataKey"), - { panx: 0, pany: 0, scale: 1, width: 500, height: 500, layoutKeys: [KeyStore.Data] }); + function CreateCollectionPrototype(): Document { + let collProto = setupPrototypeOptions(collProtoId, "COLLECTION_PROTO", CollectionView.LayoutString("DataKey"), + { panx: 0, pany: 0, scale: 1, width: 500, height: 500, layoutKeys: [KeyStore.Data] }); + return collProto; } - function GetKVPPrototype(): Document { - return kvpProto ? kvpProto : - kvpProto = setupPrototypeOptions(kvpProtoId, "KVP_PROTO", KeyValueBox.LayoutString(), - { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] }) + function CreateKVPPrototype(): Document { + let kvpProto = setupPrototypeOptions(kvpProtoId, "KVP_PROTO", KeyValueBox.LayoutString(), + { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] }); + return kvpProto; } - function GetVideoPrototype(): Document { - if (!videoProto) { - videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("AnnotationsKey"), - { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }); - videoProto.SetNumber(KeyStore.CurPage, 0); - videoProto.SetText(KeyStore.BackgroundLayout, VideoBox.LayoutString()); - } + function CreateVideoPrototype(): Document { + let videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("AnnotationsKey"), + { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }); + videoProto.SetNumber(KeyStore.CurPage, 0); + videoProto.SetText(KeyStore.BackgroundLayout, VideoBox.LayoutString()); return videoProto; } - function GetAudioPrototype(): Document { - return audioProto ? audioProto : - audioProto = setupPrototypeOptions(audioProtoId, "AUDIO_PROTO", AudioBox.LayoutString(), - { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] }) + function CreateAudioPrototype(): Document { + let audioProto = setupPrototypeOptions(audioProtoId, "AUDIO_PROTO", AudioBox.LayoutString(), + { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] }) + return audioProto; } @@ -185,44 +182,44 @@ export namespace Documents { // return doc; } export function VideoDocument(url: string, options: DocumentOptions = {}) { - return assignToDelegate(SetInstanceOptions(GetVideoPrototype(), options, [new URL(url), VideoField]), options); + return assignToDelegate(SetInstanceOptions(videoProto, options, [new URL(url), VideoField]), options); } export function AudioDocument(url: string, options: DocumentOptions = {}) { - return assignToDelegate(SetInstanceOptions(GetAudioPrototype(), options, [new URL(url), AudioField]), options); + return assignToDelegate(SetInstanceOptions(audioProto, options, [new URL(url), AudioField]), options); } export function HistogramDocument(histoOp: HistogramOperation, options: DocumentOptions = {}, id?: string, delegId?: string) { - return assignToDelegate(SetInstanceOptions(GetHistogramPrototype(), options, [histoOp, HistogramField], id).MakeDelegate(delegId), options); + return assignToDelegate(SetInstanceOptions(histoProto, options, [histoOp, HistogramField], id).MakeDelegate(delegId), options); } export function TextDocument(options: DocumentOptions = {}) { - return assignToDelegate(SetInstanceOptions(GetTextPrototype(), options, ["", TextField]).MakeDelegate(), options); + return assignToDelegate(SetInstanceOptions(textProto, options, ["", TextField]).MakeDelegate(), options); } export function PdfDocument(url: string, options: DocumentOptions = {}) { - return assignToDelegate(SetInstanceOptions(GetPdfPrototype(), options, [new URL(url), PDFField]).MakeDelegate(), options); + return assignToDelegate(SetInstanceOptions(pdfProto, options, [new URL(url), PDFField]).MakeDelegate(), options); } export function WebDocument(url: string, options: DocumentOptions = {}) { - return assignToDelegate(SetInstanceOptions(GetWebPrototype(), options, [new URL(url), WebField]).MakeDelegate(), options); + return assignToDelegate(SetInstanceOptions(webProto, options, [new URL(url), WebField]).MakeDelegate(), options); } export function HtmlDocument(html: string, options: DocumentOptions = {}) { - return assignToDelegate(SetInstanceOptions(GetWebPrototype(), options, [html, HtmlField]).MakeDelegate(), options); + return assignToDelegate(SetInstanceOptions(webProto, options, [html, HtmlField]).MakeDelegate(), options); } export function KVPDocument(document: Document, options: DocumentOptions = {}, id?: string) { - return assignToDelegate(SetInstanceOptions(GetKVPPrototype(), options, document, id), options) + return assignToDelegate(SetInstanceOptions(kvpProto, options, document, id), options) } export function FreeformDocument(documents: Array, options: DocumentOptions, id?: string, makePrototype: boolean = true) { if (!makePrototype) { - return SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id) + return SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id) } - return assignToDelegate(SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id).MakeDelegate(), options) + return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Freeform }, [documents, ListField], id).MakeDelegate(), options) } export function SchemaDocument(documents: Array, options: DocumentOptions, id?: string) { - return assignToDelegate(SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Schema }, [documents, ListField], id), options) + return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Schema }, [documents, ListField], id), options) } export function TreeDocument(documents: Array, options: DocumentOptions, id?: string) { - return assignToDelegate(SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Tree }, [documents, ListField], id), options) + return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Tree }, [documents, ListField], id), options) } export function DockDocument(config: string, options: DocumentOptions, id?: string) { - return assignToDelegate(SetInstanceOptions(GetCollectionPrototype(), { ...options, viewType: CollectionViewType.Docking }, [config, TextField], id), options) + return assignToDelegate(SetInstanceOptions(collProto, { ...options, viewType: CollectionViewType.Docking }, [config, TextField], id), options) } export function CaptionDocument(doc: Document) { diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index c9467e130..fd08782ff 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -321,7 +321,7 @@ export class Main extends React.Component { isShown={this.areWorkspacesShown} toggle={this.toggleWorkspaces} /> } return ( - [ + <>
runInAction(() => { @@ -339,9 +339,9 @@ export class Main extends React.Component { {this.miscButtons} {workspaceMenu} -
, - this.activeTextBox - ] + + {this.activeTextBox} + ); } -- cgit v1.2.3-70-g09d2