From fd329ad25987122c8f2a31177a6c346c97f00457 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 25 Feb 2021 18:54:45 -0500 Subject: added 'proto' drag option for dropping proto of document. auto add of non annotations to file system. auto added delegates & aliases to a docuemnt's 'alias' field. --- src/client/views/LightboxView.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 6 +----- src/client/views/collections/CollectionView.tsx | 5 ++--- src/client/views/collections/TreeView.tsx | 16 ++++++++++------ .../views/collections/collectionFreeForm/MarqueeView.tsx | 4 ++-- 5 files changed, 16 insertions(+), 17 deletions(-) (limited to 'src/client/views') diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index babc518ff..e1fbea76e 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -46,7 +46,7 @@ export class LightboxView extends React.Component { this._docFilters && (this._docFilters.length = 0); this._future = this._history = []; } else { - TabDocView.PinDoc(doc, { hidePresBox: true }); + //TabDocView.PinDoc(doc, { hidePresBox: true }); this._history ? this._history.push({ doc, target }) : this._history = [{ doc, target }]; if (doc !== LightboxView.LightboxDoc) { this._savedState = { diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index a9438f8f7..d5fa81024 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -253,11 +253,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: e.stopPropagation(); e.preventDefault(); - const addDocument = (doc: Doc | Doc[]) => { - const docs = doc instanceof Doc ? [doc] : doc; - docs.forEach(doc => Doc.AddDocToList(Cast(Doc.UserDoc().myFileOrphans, Doc, null), "data", doc)); - return this.addDocument(doc); - }; + const addDocument = (doc: Doc | Doc[]) => this.addDocument(doc); if (html) { if (FormattedTextBox.IsFragment(html)) { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index f305174f1..a217de193 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -153,12 +153,10 @@ export class CollectionView extends Touchable { const hasContextAnchor = DocListCast(doc.links).some(l => (l.anchor2 === doc && Cast(l.anchor1, Doc, null)?.annotationOn === context) || (l.anchor1 === doc && Cast(l.anchor2, Doc, null)?.annotationOn === context)); if (context && !hasContextAnchor && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG)) { const pushpin = Docs.Create.FontIconDocument({ - title: "pushpin", label: "", + title: "pushpin", label: "", annotationOn: Cast(doc.annotationOn, Doc, null), isPushpin: true, icon: "map-pin", x: Cast(doc.x, "number", null), y: Cast(doc.y, "number", null), _backgroundColor: "#0000003d", color: "#ACCEF7", _width: 15, _height: 15, _xPadding: 0, isLinkButton: true, _timecodeToShow: Cast(doc._timecodeToShow, "number", null) }); - pushpin.isPushpin = true; - Doc.GetProto(pushpin).annotationOn = doc.annotationOn; Doc.SetInPlace(doc, "annotationOn", undefined, true); Doc.AddDocToList(context, Doc.LayoutFieldKey(context) + "-annotations", pushpin); const pushpinLink = DocUtils.MakeLink({ doc: pushpin }, { doc: doc }, "pushpin", ""); @@ -191,6 +189,7 @@ export class CollectionView extends Touchable { const ind = (targetDataDoc[this.props.fieldKey] as List).indexOf(doc); if (ind !== -1) { Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc); + doc.context = undefined; recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true); } }); diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index ac19a3591..0ffc2df25 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -101,13 +101,13 @@ export class TreeView extends React.Component { @observable _dref: DocumentView | undefined | null; get displayName() { return "TreeView(" + this.props.document.title + ")"; } // this makes mobx trace() statements more descriptive get treeViewLockExpandedView() { return this.doc.treeViewLockExpandedView; } - get defaultExpandedView() { return StrCast(this.doc.treeViewDefaultExpandedView, this.fileSysMode ? "data" : Doc.UserDoc().noviceMode || this.outlineMode ? "layout" : "fields"); } + get defaultExpandedView() { return StrCast(this.doc.treeViewDefaultExpandedView, this.fileSysMode ? (this.doc.isFolder ? "data" : "layout") : Doc.UserDoc().noviceMode || this.outlineMode ? "layout" : "fields"); } get treeViewDefaultExpandedView() { return this.treeViewLockExpandedView ? this.defaultExpandedView : (this.childDocs && !this.fileSysMode ? this.fieldKey : this.defaultExpandedView); } @computed get doc() { TraceMobx(); return this.props.document; } @computed get outlineMode() { return this.props.treeView.doc.treeViewType === "outline"; } @computed get fileSysMode() { return this.props.treeView.doc.treeViewType === "fileSystem"; } - @computed get treeViewOpen() { return (!this.props.treeViewPreventOpen && !this.doc.treeViewPreventOpen && BoolCast(this.doc.treeViewOpen)) || this._overrideTreeViewOpen; } + @computed get treeViewOpen() { return (!this.props.treeViewPreventOpen && !this.doc.treeViewPreventOpen && Doc.GetT(this.doc, "treeViewOpen", "boolean", true)) || this._overrideTreeViewOpen; } @computed get treeViewExpandedView() { return StrCast(this.doc.treeViewExpandedView, this.treeViewDefaultExpandedView); } @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.containingCollection.maxEmbedHeight, 200); } @computed get dataDoc() { return this.doc[DataSym]; } @@ -123,7 +123,7 @@ export class TreeView extends React.Component { const layout = Doc.LayoutField(this.doc) instanceof Doc ? Doc.LayoutField(this.doc) as Doc : undefined; return ((this.props.dataDoc ? DocListCastOrNull(this.props.dataDoc[field]) : undefined) || // if there's a data doc for an expanded template, use it's data field (layout ? DocListCastOrNull(layout[field]) : undefined) || // else if there's a layout doc, display it's fields - DocListCastOrNull(this.doc[field])); // otherwise use the document's data field + DocListCastOrNull(this.doc[field]))?.filter(doc => !this.fileSysMode || field !== "aliases" || Doc.GetT(doc, "context", Doc, true)); // otherwise use the document's data field } @undoBatch move = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => { return this.doc !== target && this.props.removeDoc?.(doc) === true && addDoc(doc); @@ -477,8 +477,8 @@ export class TreeView extends React.Component { { if (this.fileSysMode) { - this.doc.treeViewExpandedView = this.doc.isFolder ? this.fieldKey : this.treeViewExpandedView === "layout" ? "fields" : - this.treeViewExpandedView === "fields" ? "aliases" : "layout"; + this.doc.treeViewExpandedView = this.doc.isFolder ? this.fieldKey : this.treeViewExpandedView === "layout" ? "aliases" : + this.treeViewExpandedView === "aliases" && !Doc.UserDoc().noviceMode ? "fields" : "layout"; } else if (this.treeViewOpen) { this.doc.treeViewExpandedView = this.treeViewLockExpandedView ? this.doc.treeViewExpandedView : this.treeViewExpandedView === this.fieldKey ? (Doc.UserDoc().noviceMode || this.outlineMode ? "layout" : "fields") : @@ -495,7 +495,11 @@ export class TreeView extends React.Component { } showContextMenu = (e: React.MouseEvent) => simulateMouseClick(this._docRef?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30); - contextMenuItems = () => this.doc.isFolder ? [{ script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" }] : Doc.IsSystem(this.doc) ? [] : [{ script: ScriptField.MakeFunction(`openOnRight(self)`)!, label: "Open" }, { script: ScriptField.MakeFunction(`DocFocus(self)`)!, label: "Focus" }]; + contextMenuItems = () => this.doc.isFolder ? + [{ script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" }] : Doc.IsSystem(this.doc) ? [] : + this.fileSysMode && this.doc === Doc.GetProto(this.doc) ? + [{ script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" }] : + [{ script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }]; truncateTitleWidth = () => NumCast(this.props.treeView.props.Document.treeViewTruncateTitleWidth, this.props.panelWidth()); onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick)); onChildDoubleClick = () => (!this.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick); diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 9e442a8c8..34ddf6ed2 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -167,7 +167,7 @@ export class MarqueeView extends React.Component Date: Thu, 25 Feb 2021 19:16:36 -0500 Subject: prevent annotation notes on PDFS from showing up in file system view. --- src/client/util/DragManager.ts | 4 ++-- src/client/views/MarqueeAnnotator.tsx | 4 ++-- src/client/views/collections/CollectionSubView.tsx | 2 +- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/client/views') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 0a3928ff8..9baefd247 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -155,7 +155,7 @@ export namespace DragManager { // used by PDFs,Text,Image,Video,Web to conditionally (if the drop completes) create a text annotation when dragging the annotate button from the AnchorMenu when a text/region selection has been made. // this is pretty clunky and should be rethought out using linkDrag or DocumentDrag export class AnchorAnnoDragData { - constructor(dragDoc: Doc, annotationDocCreator: () => Doc, dropDocCreator: () => Doc) { + constructor(dragDoc: Doc, annotationDocCreator: () => Doc, dropDocCreator: (annotationOn?: Doc) => Doc) { this.dragDocument = dragDoc; this.dropDocCreator = dropDocCreator; this.annotationDocCreator = annotationDocCreator; @@ -164,7 +164,7 @@ export namespace DragManager { targetContext: Doc | undefined; dragDocument: Doc; annotationDocCreator: () => Doc; - dropDocCreator: () => Doc; + dropDocCreator: (asAnnotation?: Doc) => Doc; dropDocument?: Doc; annotationDocument?: Doc; offset: number[]; diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx index 6e8f9a2df..1fb87f522 100644 --- a/src/client/views/MarqueeAnnotator.tsx +++ b/src/client/views/MarqueeAnnotator.tsx @@ -67,8 +67,8 @@ export class MarqueeAnnotator extends React.Component { AnchorMenu.Instance.StartDrag = action(async (e: PointerEvent, ele: HTMLElement) => { e.preventDefault(); e.stopPropagation(); - const targetCreator = () => { - const target = CurrentUserUtils.GetNewTextDoc("Note linked to " + this.props.rootDoc.title, 0, 0, 100, 100); + const targetCreator = (asAnnotation?: Doc) => { + const target = CurrentUserUtils.GetNewTextDoc("Note linked to " + this.props.rootDoc.title, 0, 0, 100, 100, undefined, asAnnotation); FormattedTextBox.SelectOnLoad = target[Id]; return target; }; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index d5fa81024..b0c665aa8 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -227,7 +227,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: else if (de.complete.annoDragData && (!this.props.isAnnotationOverlay || de.complete.annoDragData.dragDocument === this.props.Document)) { e.stopPropagation(); de.complete.annoDragData.annotationDocument = de.complete.annoDragData.annotationDocCreator(); - de.complete.annoDragData.dropDocument = de.complete.annoDragData.dropDocCreator(); + de.complete.annoDragData.dropDocument = de.complete.annoDragData.dropDocCreator(this.props.isAnnotationOverlay ? this.props.Document : undefined); return de.complete.annoDragData.dropDocument && this.addDocument(de.complete.annoDragData.dropDocument); } return false; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index b4fbda9f4..f4105f313 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -231,8 +231,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp AnchorMenu.Instance.StartDrag = action(async (e: PointerEvent, ele: HTMLElement) => { e.preventDefault(); e.stopPropagation(); - const targetCreator = () => { - const target = CurrentUserUtils.GetNewTextDoc("Note linked to " + this.rootDoc.title, 0, 0, 100, 100); + const targetCreator = (annotationOn?: Doc) => { + const target = CurrentUserUtils.GetNewTextDoc("Note linked to " + this.rootDoc.title, 0, 0, 100, 100, undefined, annotationOn); FormattedTextBox.SelectOnLoad = target[Id]; return target; }; -- cgit v1.2.3-70-g09d2 From f6ed4c2eb2600282d2f9a31433c5fc24d2928fab Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 25 Feb 2021 19:19:00 -0500 Subject: add all aliases to file sys view (don't filter out those without contexts) --- src/client/views/collections/TreeView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views') diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 0ffc2df25..513ef4015 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -123,7 +123,7 @@ export class TreeView extends React.Component { const layout = Doc.LayoutField(this.doc) instanceof Doc ? Doc.LayoutField(this.doc) as Doc : undefined; return ((this.props.dataDoc ? DocListCastOrNull(this.props.dataDoc[field]) : undefined) || // if there's a data doc for an expanded template, use it's data field (layout ? DocListCastOrNull(layout[field]) : undefined) || // else if there's a layout doc, display it's fields - DocListCastOrNull(this.doc[field]))?.filter(doc => !this.fileSysMode || field !== "aliases" || Doc.GetT(doc, "context", Doc, true)); // otherwise use the document's data field + DocListCastOrNull(this.doc[field]))?.filter(doc => !this.fileSysMode || field !== "aliases");// || Doc.GetT(doc, "context", Doc, true)); // otherwise use the document's data field } @undoBatch move = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => { return this.doc !== target && this.props.removeDoc?.(doc) === true && addDoc(doc); -- cgit v1.2.3-70-g09d2 From 97cdf8bd071bd3187e0db0e22e18ce705f30d57f Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 25 Feb 2021 21:28:37 -0500 Subject: field info start --- src/client/documents/Documents.ts | 234 +++++++++++++++++++++++++++++++++--- src/client/util/CurrentUserUtils.ts | 1 + src/client/views/Main.tsx | 10 +- src/client/views/nodes/LabelBox.tsx | 2 +- 4 files changed, 225 insertions(+), 22 deletions(-) (limited to 'src/client/views') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1acba01a9..905ca324c 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -59,21 +59,26 @@ import { DocumentType } from "./DocumentTypes"; const path = require('path'); const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace("px", "")); +interface dinfo { + description: string; + type: string; + dflt?: any; +} export interface DocumentOptions { - system?: boolean; - _autoHeight?: boolean; - _headerHeight?: number; // height of header of custom notes - _headerFontSize?: number; // font size of header of custom notes - _headerPointerEvents?: string; // types of events the header of a custom text document can consume - _panX?: number; - _panY?: number; - _width?: number; - _height?: number; - _nativeWidth?: number; - _nativeHeight?: number; - _dimMagnitude?: number; // magnitude of collectionMulti{row,col} view element - _dimUnit?: string; // "px" or "*" (default = "*") - _fitWidth?: boolean; + system?: boolean | dinfo; + _autoHeight?: boolean | dinfo; + _headerHeight?: number | dinfo; // height of header of custom notes + _headerFontSize?: number | dinfo; // font size of header of custom notes + _headerPointerEvents?: string | dinfo; // types of events the header of a custom text document can consume + _panX?: number | dinfo; + _panY?: number | dinfo; + _width?: number | dinfo; + _height?: number | dinfo; + _nativeWidth?: number | dinfo; + _nativeHeight?: number | dinfo; + _dimMagnitude?: number | dinfo; // magnitude of collectionMulti{row,col} view element + _dimUnit?: string | dinfo; // "px" or "*" (default = "*") + _fitWidth?: boolean | dinfo; _fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents _freeformLOD?: boolean; // whether to use LOD to render a freeform document _showTitle?: string; // field name to display in header (:hover is an optional suffix) @@ -232,8 +237,184 @@ export interface DocumentOptions { isLabel?: boolean; // whether the document is a label or not (video / audio) useLinkSmallAnchor?: boolean; // whether links to this document should use a miniature linkAnchorBox border?: string; //for searchbox - hovercolor?: string; + _hovercolor?: string; } +/* +let _docOptions: DocumentOptions = { + system: { type: "string", description: "is document created/owned by the system", dflt: false }, + _autoHeight: { type: "boolean", description: "whether document automatically resizes vertically to display contents", dflt: false }, + _headerHeight: { type: "number", description: "height of document header used for displaying title", dflt: 20 }, + _headerFontSize: { type: "number", description: "font size of header of custom notes", dflt: 12 }, + _headerPointerEvents: { type: "string", description: "types of events the header of a custom text document can consume" }, + _panX: { type: "number", description: "horizontal pan location of a freeform view" }, + _panY: { type: "number", description: "vertical pan location of a freeform view" }, + _width: { type: "number", description: "displayed width of a document" }, + _height: { type: "number", description: "displayed height of document" }, + _nativeWidth: { type: "number", description: "native width of document contents (e.g., the pixel width of an image)" }, + _nativeHeight: { type: "number", description: "native height of document contents (e.g., the pixel height of an image)" }, + _dimMagnitude: { type: "number", description: "magnitude of collectionMulti{row,col} element's width or height" }, + _dimUnit: { type: "string", description: "units of collectionMulti{row,col} element's width or height - 'px' or '*' for pixels or relative units" }, + _fitWidth: { type: "boolean", description: "whether document should scale its contents to fit its rendered width or not (e.g., for PDFviews)" } + /*_fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents + _freeformLOD?: boolean; // whether to use LOD to render a freeform document + _showTitle?: string; // field name to display in header (:hover is an optional suffix) + _showCaption?: string; // which field to display in the caption area. leave empty to have no caption + _scrollTop?: number; // scroll location for pdfs + _noAutoscroll?: boolean;// whether collections autoscroll when this item is dragged + _chromeStatus?: string; + _searchDoc?: boolean; // is this a search document (used to change UI for search results in schema view) + _viewType?: string; // sub type of a collection + _gridGap?: number; // gap between items in masonry view + _xMargin?: number; // gap between left edge of document and start of masonry/stacking layouts + _yMargin?: number; // gap between top edge of dcoument and start of masonry/stacking layouts + _xPadding?: number; + _yPadding?: number; + _itemIndex?: number; // which item index the carousel viewer is showing + _showSidebar?: boolean; //whether an annotationsidebar should be displayed for text docuemnts + _singleLine?: boolean; // whether text document is restricted to a single line (carriage returns make new document) + "_carousel-caption-xMargin"?: number; + "_carousel-caption-yMargin"?: number; + x?: number; + y?: number; + z?: number; + author?: string; + _hideContextMenu?: boolean; // whether the context menu can be shown + dropAction?: dropActionType; + childDropAction?: dropActionType; + targetDropAction?: dropActionType; + layoutKey?: string; + type?: string; + title?: string; + version?: string; // version identifier for a document + label?: string; + hidden?: boolean; + userDoc?: Doc; // the userDocument + toolTip?: string; // tooltip to display on hover + style?: string; + page?: number; + dontUndo?: boolean; // whether button clicks should be undoable (this is set to true for Undo/Redo/and sidebar buttons that open the siebar panel) + description?: string; // added for links + _viewScale?: number; + _overflow?: string; + forceActive?: boolean; + layout?: string | Doc; // default layout string for a document + contentPointerEvents?: string; // pointer events allowed for content of a document view. eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents + childLimitHeight?: number; // whether to limit the height of colleciton children. 0 - means height can be no bigger than width + childLayoutTemplate?: Doc; // template for collection to use to render its children (see PresBox or Buxton layout in tree view) + childLayoutString?: string; // template string for collection to use to render its children + hideLinkButton?: boolean; // whether the blue link counter button should be hidden + hideAllLinks?: boolean; // whether all individual blue anchor dots should be hidden + _columnsHideIfEmpty?: boolean; // whether stacking view column headings should be hidden + isTemplateForField?: string; // the field key for which the containing document is a rendering template + isTemplateDoc?: boolean; + watchedDocuments?: Doc; // list of documents to "watch" in an icon doc to display a badge + targetScriptKey?: string; // where to write a template script (used by collections with click templates which need to target onClick, onDoubleClick, etc) + templates?: List; + hero?: ImageField; // primary image that best represents a compound document (e.g., for a buxton device document that has multiple images) + backgroundColor?: string | ScriptField; // background color for data doc + _backgroundColor?: string | ScriptField; // background color for each template layout doc ( overrides backgroundColor ) + color?: string; // foreground color data doc + _color?: string; // foreground color for each template layout doc (overrides color) + _clipWidth?: number; // percent transition from before to after in comparisonBox + caption?: RichTextField; + ignoreClick?: boolean; + lockedPosition?: boolean; // lock the x,y coordinates of the document so that it can't be dragged + _lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed + isAnnotating?: boolean; // whether we web document is annotation mode where links can't be clicked to allow annotations to be created + opacity?: number; + defaultBackgroundColor?: string; + _layers?: List; + _raiseWhenDragged?: boolean; // whether a document is brought to front when dragged. + isLinkButton?: boolean; + isFolder?: boolean; + _columnWidth?: number; + _fontSize?: string; + _fontWeight?: number; + _fontFamily?: string; + _curPage?: number; + _currentTimecode?: number; // the current timecode of a time-based document (e.g., current time of a video) value is in seconds + _currentFrame?: number; // the current frame of a frame-based collection (e.g., progressive slide) + _timecodeToShow?: number; // the time that a document should be displayed (e.g., when an annotation shows up as a video plays) + _timecodeToHide?: number; // the time that a document should be hidden + _timelineLabel?: boolean; // whether the document exists on a timeline + lastFrame?: number; // the last frame of a frame-based collection (e.g., progressive slide) + activeFrame?: number; // the active frame of a document in a frame base collection + appearFrame?: number; // the frame in which the document appears + presTransition?: number; //the time taken for the transition TO a document + presDuration?: number; //the duration of the slide in presentation view + presProgressivize?: boolean; + borderRounding?: string; + boxShadow?: string; + dontRegisterChildViews?: boolean; + dontRegisterView?: boolean; + lookupField?: ScriptField; // script that returns the value of a field. This script is passed the rootDoc, layoutDoc, field, and container of the document. see PresBox. + "onDoubleClick-rawScript"?: string; // onDoubleClick script in raw text form + "onChildDoubleClick-rawScript"?: string; // onChildDoubleClick script in raw text form + "onChildClick-rawScript"?: string; // on ChildClick script in raw text form + "onClick-rawScript"?: string; // onClick script in raw text form + "onCheckedClick-rawScript"?: string; // onChecked script in raw text form + "onCheckedClick-params"?: List; // parameter list for onChecked treeview functions + _pivotField?: string; // field key used to determine headings for sections in stacking, masonry, pivot views + _columnHeaders?: List; // headers for stacking views + _schemaHeaders?: List; // headers for schema view + dockingConfig?: string; + annotationOn?: Doc; + isPushpin?: boolean; + removeDropProperties?: List; // list of properties that should be removed from a document when it is dropped. e.g., a creator button may be forceActive to allow it be dragged, but the forceActive property can be removed from the dropped document + dbDoc?: Doc; + iconShape?: string; // shapes of the fonticon border + linkRelationship?: string; // type of relatinoship a link represents + ischecked?: ScriptField; // returns whether a font icon box is checked + activeInkPen?: Doc; // which pen document is currently active (used as the radio button state for the 'unhecked' pen tool scripts) + onClick?: ScriptField; + onDoubleClick?: ScriptField; + onChildClick?: ScriptField; // script given to children of a collection to execute when they are clicked + onChildDoubleClick?: ScriptField; // script given to children of a collection to execute when they are double clicked + onPointerDown?: ScriptField; + onPointerUp?: ScriptField; + dropConverter?: ScriptField; // script to run when documents are dropped on this Document. + dragFactory?: Doc; // document to create when dragging with a suitable onDragStart script + clickFactory?: Doc; // document to create when clicking on a button with a suitable onClick script + onDragStart?: ScriptField; //script to execute at start of drag operation -- e.g., when a "creator" button is dragged this script generates a different document to drop + clipboard?: Doc; + useCors?: boolean; + icon?: string; + target?: Doc; // available for use in scripts as the primary target document + sourcePanel?: Doc; // panel to display in 'targetContainer' as the result of a button onClick script + targetContainer?: Doc; // document whose proto will be set to 'panel' as the result of a onClick click script + searchFileTypes?: List; // file types allowed in a search query + strokeWidth?: number; + cloneFieldFilter?: List; // fields not to copy when the document is cloned + _stayInCollection?: boolean;// whether the document should remain in its collection when someone tries to drag and drop it elsewhere + freezeChildren?: string; // whether children are now allowed to be added and or removed from a collection + treeViewPreventOpen?: boolean; // ignores the treeViewOpen Doc flag which allows a treeViewItem's expand/collapse state to be independent of other views of the same document in the tree view + treeViewHideTitle?: boolean; // whether to hide the top document title of a tree view + treeViewHideHeader?: boolean; // whether to hide the header for a document in a tree view + treeViewHideHeaderFields?: boolean; // whether to hide the drop down options for tree view items. + treeViewOpen?: boolean; // whether this document is expanded in a tree view + treeViewExpandedView?: string; // which field/thing is displayed when this item is opened in tree view + treeViewChecked?: ScriptField; // script to call when a tree view checkbox is checked + treeViewTruncateTitleWidth?: number; + treeViewType?: string; // whether treeview is a Slide, file system, or (default) collection hierarchy + treeViewLockExpandedView?: boolean; // whether the expanded view can be changed + treeViewDefaultExpandedView?: string; // default expanded view + sidebarColor?: string; // background color of text sidebar + sidebarViewType?: string; // collection type of text sidebar + limitHeight?: number; // maximum height for newly created (eg, from pasting) text documents + // [key: string]: Opt; + pointerHack?: boolean; // for buttons, allows onClick handler to fire onPointerDown + textTransform?: string; // is linear view expanded + letterSpacing?: string; // is linear view expanded + flexDirection?: "unset" | "row" | "column" | "row-reverse" | "column-reverse"; + selectedIndex?: number; + syntaxColor?: string; // can be applied to text for syntax highlighting all matches in the text + searchQuery?: string; // for quersyBox + linearViewIsExpanded?: boolean; // is linear view expanded + isLabel?: boolean; // whether the document is a label or not (video / audio) + useLinkSmallAnchor?: boolean; // whether links to this document should use a miniature linkAnchorBox + border?: string; //for searchbox + _hovercolor?: string; +}*/ class EmptyBox { public static LayoutString() { @@ -243,6 +424,29 @@ class EmptyBox { export namespace Docs { + export let FieldInfos: Doc | undefined; + export async function setupFieldInfos() { + const fieldDocs = await DocServer.GetRefField("FIELDS"); + if (fieldDocs instanceof Doc) { + Docs.FieldInfos = fieldDocs; + } else { + runInAction(() => { + const infos = Docs.FieldInfos = new Doc("FIELDS", true); + const keys = Object.keys(_docOptions); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const options = (_docOptions as any)[key] as dinfo; + const finfo = new Doc(); + finfo.name = key; + finfo.default = options.dflt; + finfo.description = options.description; + finfo.type = options.type; + infos[key] = finfo; + } + }); + } + } + export let newAccount: boolean = false; export namespace Prototypes { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 8ef52e02a..3413f7b05 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1069,6 +1069,7 @@ export class CurrentUserUtils { } public static async loadUserDocument(id: string) { + //await Docs.setupFieldInfos(); this.curr_id = id; await rp.get(Utils.prepend("/getUserDocumentIds")).then(ids => { const { userDocumentId, sharingDocumentId, linkDatabaseId } = JSON.parse(ids); diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 92f6ae028..5063c6f6b 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -1,12 +1,10 @@ -import { MainView } from "./MainView"; -import { Docs } from "../documents/Documents"; -import { CurrentUserUtils } from "../util/CurrentUserUtils"; -import * as ReactDOM from 'react-dom'; import * as React from 'react'; -import { DocServer } from "../DocServer"; +import * as ReactDOM from 'react-dom'; import { AssignAllExtensions } from "../../extensions/General/Extensions"; -import { Networking } from "../Network"; +import { Docs } from "../documents/Documents"; +import { CurrentUserUtils } from "../util/CurrentUserUtils"; import { CollectionView } from "./collections/CollectionView"; +import { MainView } from "./MainView"; AssignAllExtensions(); diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index 87d5b07a2..3d4429a55 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -59,7 +59,7 @@ export class LabelBox extends ViewBoxBaseComponent m + ":").join(" ") + ")") -- cgit v1.2.3-70-g09d2 From 414c48bc240a0dcfc57c07ece61eb6cca0cbf5bb Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 25 Feb 2021 21:52:50 -0500 Subject: wokring field infos. --- src/client/documents/Documents.ts | 10 ++++++---- src/client/util/CurrentUserUtils.ts | 3 ++- src/client/views/Main.tsx | 10 ++++++---- 3 files changed, 14 insertions(+), 9 deletions(-) (limited to 'src/client/views') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 905ca324c..b5b179d3a 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -239,7 +239,7 @@ export interface DocumentOptions { border?: string; //for searchbox _hovercolor?: string; } -/* + let _docOptions: DocumentOptions = { system: { type: "string", description: "is document created/owned by the system", dflt: false }, _autoHeight: { type: "boolean", description: "whether document automatically resizes vertically to display contents", dflt: false }, @@ -255,7 +255,9 @@ let _docOptions: DocumentOptions = { _dimMagnitude: { type: "number", description: "magnitude of collectionMulti{row,col} element's width or height" }, _dimUnit: { type: "string", description: "units of collectionMulti{row,col} element's width or height - 'px' or '*' for pixels or relative units" }, _fitWidth: { type: "boolean", description: "whether document should scale its contents to fit its rendered width or not (e.g., for PDFviews)" } - /*_fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents + +} +/*_fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents _freeformLOD?: boolean; // whether to use LOD to render a freeform document _showTitle?: string; // field name to display in header (:hover is an optional suffix) _showCaption?: string; // which field to display in the caption area. leave empty to have no caption @@ -426,12 +428,12 @@ export namespace Docs { export let FieldInfos: Doc | undefined; export async function setupFieldInfos() { - const fieldDocs = await DocServer.GetRefField("FIELDS"); + const fieldDocs = await DocServer.GetRefField("FieldInfos"); if (fieldDocs instanceof Doc) { Docs.FieldInfos = fieldDocs; } else { runInAction(() => { - const infos = Docs.FieldInfos = new Doc("FIELDS", true); + const infos = Docs.FieldInfos = new Doc("FieldInfos", true); const keys = Object.keys(_docOptions); for (let i = 0; i < keys.length; i++) { const key = keys[i]; diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 3413f7b05..dcaf61fea 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1050,6 +1050,7 @@ export class CurrentUserUtils { // } // }); setTimeout(() => DocServer.UPDATE_SERVER_CACHE(), 2500); + doc.fieldInfos = Docs.FieldInfos; return doc; } @@ -1069,7 +1070,7 @@ export class CurrentUserUtils { } public static async loadUserDocument(id: string) { - //await Docs.setupFieldInfos(); + await Docs.setupFieldInfos(); this.curr_id = id; await rp.get(Utils.prepend("/getUserDocumentIds")).then(ids => { const { userDocumentId, sharingDocumentId, linkDatabaseId } = JSON.parse(ids); diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 5063c6f6b..92f6ae028 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -1,10 +1,12 @@ -import * as React from 'react'; -import * as ReactDOM from 'react-dom'; -import { AssignAllExtensions } from "../../extensions/General/Extensions"; +import { MainView } from "./MainView"; import { Docs } from "../documents/Documents"; import { CurrentUserUtils } from "../util/CurrentUserUtils"; +import * as ReactDOM from 'react-dom'; +import * as React from 'react'; +import { DocServer } from "../DocServer"; +import { AssignAllExtensions } from "../../extensions/General/Extensions"; +import { Networking } from "../Network"; import { CollectionView } from "./collections/CollectionView"; -import { MainView } from "./MainView"; AssignAllExtensions(); -- cgit v1.2.3-70-g09d2 From feac7f17533c4b587cadc783fbd5f47c464d40db Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 26 Feb 2021 02:24:32 -0500 Subject: updated fieldInfos a bit more. --- src/client/documents/Documents.ts | 301 +++++++--------------------- src/client/util/CurrentUserUtils.ts | 3 +- src/client/views/LightboxView.tsx | 2 +- src/client/views/collections/TabDocView.tsx | 3 +- src/client/views/collections/TreeView.tsx | 2 +- 5 files changed, 77 insertions(+), 234 deletions(-) (limited to 'src/client/views') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index b5b179d3a..de08040e2 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -25,6 +25,7 @@ import { DirectoryImportBox } from "../util/Import & Export/DirectoryImportBox"; import { LinkManager } from "../util/LinkManager"; import { Scripting } from "../util/Scripting"; import { undoBatch, UndoManager } from "../util/UndoManager"; +import { DimUnit } from "../views/collections/collectionMulticolumn/CollectionMulticolumnView"; import { CollectionDockingView } from "../views/collections/CollectionDockingView"; import { CollectionView, CollectionViewType } from "../views/collections/CollectionView"; import { ContextMenu } from "../views/ContextMenu"; @@ -59,205 +60,56 @@ import { DocumentType } from "./DocumentTypes"; const path = require('path'); const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace("px", "")); -interface dinfo { - description: string; - type: string; - dflt?: any; +class EmptyBox { + public static LayoutString() { + return ""; + } } -export interface DocumentOptions { - system?: boolean | dinfo; - _autoHeight?: boolean | dinfo; - _headerHeight?: number | dinfo; // height of header of custom notes - _headerFontSize?: number | dinfo; // font size of header of custom notes - _headerPointerEvents?: string | dinfo; // types of events the header of a custom text document can consume - _panX?: number | dinfo; - _panY?: number | dinfo; - _width?: number | dinfo; - _height?: number | dinfo; - _nativeWidth?: number | dinfo; - _nativeHeight?: number | dinfo; - _dimMagnitude?: number | dinfo; // magnitude of collectionMulti{row,col} view element - _dimUnit?: string | dinfo; // "px" or "*" (default = "*") - _fitWidth?: boolean | dinfo; - _fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents - _freeformLOD?: boolean; // whether to use LOD to render a freeform document - _showTitle?: string; // field name to display in header (:hover is an optional suffix) - _showCaption?: string; // which field to display in the caption area. leave empty to have no caption - _scrollTop?: number; // scroll location for pdfs - _noAutoscroll?: boolean;// whether collections autoscroll when this item is dragged - _chromeStatus?: string; - _searchDoc?: boolean; // is this a search document (used to change UI for search results in schema view) - _viewType?: string; // sub type of a collection - _gridGap?: number; // gap between items in masonry view - _xMargin?: number; // gap between left edge of document and start of masonry/stacking layouts - _yMargin?: number; // gap between top edge of dcoument and start of masonry/stacking layouts - _xPadding?: number; - _yPadding?: number; - _itemIndex?: number; // which item index the carousel viewer is showing - _showSidebar?: boolean; //whether an annotationsidebar should be displayed for text docuemnts - _singleLine?: boolean; // whether text document is restricted to a single line (carriage returns make new document) - "_carousel-caption-xMargin"?: number; - "_carousel-caption-yMargin"?: number; - x?: number; - y?: number; - z?: number; - author?: string; - _hideContextMenu?: boolean; // whether the context menu can be shown - dropAction?: dropActionType; - childDropAction?: dropActionType; - targetDropAction?: dropActionType; - layoutKey?: string; +abstract class FInfo { + description: string = ""; type?: string; - title?: string; - version?: string; // version identifier for a document - label?: string; - hidden?: boolean; - userDoc?: Doc; // the userDocument - toolTip?: string; // tooltip to display on hover - style?: string; - page?: number; - dontUndo?: boolean; // whether button clicks should be undoable (this is set to true for Undo/Redo/and sidebar buttons that open the siebar panel) - description?: string; // added for links - _viewScale?: number; - _overflow?: string; - forceActive?: boolean; - layout?: string | Doc; // default layout string for a document - contentPointerEvents?: string; // pointer events allowed for content of a document view. eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents - childLimitHeight?: number; // whether to limit the height of colleciton children. 0 - means height can be no bigger than width - childLayoutTemplate?: Doc; // template for collection to use to render its children (see PresBox or Buxton layout in tree view) - childLayoutString?: string; // template string for collection to use to render its children - hideLinkButton?: boolean; // whether the blue link counter button should be hidden - hideAllLinks?: boolean; // whether all individual blue anchor dots should be hidden - _columnsHideIfEmpty?: boolean; // whether stacking view column headings should be hidden - isTemplateForField?: string; // the field key for which the containing document is a rendering template - isTemplateDoc?: boolean; - watchedDocuments?: Doc; // list of documents to "watch" in an icon doc to display a badge - targetScriptKey?: string; // where to write a template script (used by collections with click templates which need to target onClick, onDoubleClick, etc) - templates?: List; - hero?: ImageField; // primary image that best represents a compound document (e.g., for a buxton device document that has multiple images) - backgroundColor?: string | ScriptField; // background color for data doc - _backgroundColor?: string | ScriptField; // background color for each template layout doc ( overrides backgroundColor ) - color?: string; // foreground color data doc - _color?: string; // foreground color for each template layout doc (overrides color) - _clipWidth?: number; // percent transition from before to after in comparisonBox - caption?: RichTextField; - ignoreClick?: boolean; - lockedPosition?: boolean; // lock the x,y coordinates of the document so that it can't be dragged - _lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed - isAnnotating?: boolean; // whether we web document is annotation mode where links can't be clicked to allow annotations to be created - opacity?: number; - defaultBackgroundColor?: string; - _layers?: List; - _raiseWhenDragged?: boolean; // whether a document is brought to front when dragged. - isLinkButton?: boolean; - isFolder?: boolean; - _columnWidth?: number; - _fontSize?: string; - _fontWeight?: number; - _fontFamily?: string; - _curPage?: number; - _currentTimecode?: number; // the current timecode of a time-based document (e.g., current time of a video) value is in seconds - _currentFrame?: number; // the current frame of a frame-based collection (e.g., progressive slide) - _timecodeToShow?: number; // the time that a document should be displayed (e.g., when an annotation shows up as a video plays) - _timecodeToHide?: number; // the time that a document should be hidden - _timelineLabel?: boolean; // whether the document exists on a timeline - lastFrame?: number; // the last frame of a frame-based collection (e.g., progressive slide) - activeFrame?: number; // the active frame of a document in a frame base collection - appearFrame?: number; // the frame in which the document appears - presTransition?: number; //the time taken for the transition TO a document - presDuration?: number; //the duration of the slide in presentation view - presProgressivize?: boolean; - borderRounding?: string; - boxShadow?: string; - dontRegisterChildViews?: boolean; - dontRegisterView?: boolean; - lookupField?: ScriptField; // script that returns the value of a field. This script is passed the rootDoc, layoutDoc, field, and container of the document. see PresBox. - "onDoubleClick-rawScript"?: string; // onDoubleClick script in raw text form - "onChildDoubleClick-rawScript"?: string; // onChildDoubleClick script in raw text form - "onChildClick-rawScript"?: string; // on ChildClick script in raw text form - "onClick-rawScript"?: string; // onClick script in raw text form - "onCheckedClick-rawScript"?: string; // onChecked script in raw text form - "onCheckedClick-params"?: List; // parameter list for onChecked treeview functions - _pivotField?: string; // field key used to determine headings for sections in stacking, masonry, pivot views - _columnHeaders?: List; // headers for stacking views - _schemaHeaders?: List; // headers for schema view - dockingConfig?: string; - annotationOn?: Doc; - isPushpin?: boolean; - removeDropProperties?: List; // list of properties that should be removed from a document when it is dropped. e.g., a creator button may be forceActive to allow it be dragged, but the forceActive property can be removed from the dropped document - dbDoc?: Doc; - iconShape?: string; // shapes of the fonticon border - linkRelationship?: string; // type of relatinoship a link represents - ischecked?: ScriptField; // returns whether a font icon box is checked - activeInkPen?: Doc; // which pen document is currently active (used as the radio button state for the 'unhecked' pen tool scripts) - onClick?: ScriptField; - onDoubleClick?: ScriptField; - onChildClick?: ScriptField; // script given to children of a collection to execute when they are clicked - onChildDoubleClick?: ScriptField; // script given to children of a collection to execute when they are double clicked - onPointerDown?: ScriptField; - onPointerUp?: ScriptField; - dropConverter?: ScriptField; // script to run when documents are dropped on this Document. - dragFactory?: Doc; // document to create when dragging with a suitable onDragStart script - clickFactory?: Doc; // document to create when clicking on a button with a suitable onClick script - onDragStart?: ScriptField; //script to execute at start of drag operation -- e.g., when a "creator" button is dragged this script generates a different document to drop - clipboard?: Doc; - useCors?: boolean; - icon?: string; - target?: Doc; // available for use in scripts as the primary target document - sourcePanel?: Doc; // panel to display in 'targetContainer' as the result of a button onClick script - targetContainer?: Doc; // document whose proto will be set to 'panel' as the result of a onClick click script - searchFileTypes?: List; // file types allowed in a search query - strokeWidth?: number; - cloneFieldFilter?: List; // fields not to copy when the document is cloned - _stayInCollection?: boolean;// whether the document should remain in its collection when someone tries to drag and drop it elsewhere - freezeChildren?: string; // whether children are now allowed to be added and or removed from a collection - treeViewPreventOpen?: boolean; // ignores the treeViewOpen Doc flag which allows a treeViewItem's expand/collapse state to be independent of other views of the same document in the tree view - treeViewHideTitle?: boolean; // whether to hide the top document title of a tree view - treeViewHideHeader?: boolean; // whether to hide the header for a document in a tree view - treeViewHideHeaderFields?: boolean; // whether to hide the drop down options for tree view items. - treeViewOpen?: boolean; // whether this document is expanded in a tree view - treeViewExpandedView?: string; // which field/thing is displayed when this item is opened in tree view - treeViewChecked?: ScriptField; // script to call when a tree view checkbox is checked - treeViewTruncateTitleWidth?: number; - treeViewType?: string; // whether treeview is a Slide, file system, or (default) collection hierarchy - treeViewLockExpandedView?: boolean; // whether the expanded view can be changed - treeViewDefaultExpandedView?: string; // default expanded view - sidebarColor?: string; // background color of text sidebar - sidebarViewType?: string; // collection type of text sidebar - limitHeight?: number; // maximum height for newly created (eg, from pasting) text documents - // [key: string]: Opt; - pointerHack?: boolean; // for buttons, allows onClick handler to fire onPointerDown - textTransform?: string; // is linear view expanded - letterSpacing?: string; // is linear view expanded - flexDirection?: "unset" | "row" | "column" | "row-reverse" | "column-reverse"; - selectedIndex?: number; - syntaxColor?: string; // can be applied to text for syntax highlighting all matches in the text - searchQuery?: string; // for quersyBox - linearViewIsExpanded?: boolean; // is linear view expanded - isLabel?: boolean; // whether the document is a label or not (video / audio) - useLinkSmallAnchor?: boolean; // whether links to this document should use a miniature linkAnchorBox - border?: string; //for searchbox - _hovercolor?: string; + values?: Field[]; + layoutField?: boolean; // is this field a layout (or datadoc) field + // format?: string; // format to display values (e.g, decimal places, $, etc) + // parse?: ScriptField; // parse a value from a string + constructor(d: string, l: boolean = false) { this.description = d; this.layoutField = l; } } - -let _docOptions: DocumentOptions = { - system: { type: "string", description: "is document created/owned by the system", dflt: false }, - _autoHeight: { type: "boolean", description: "whether document automatically resizes vertically to display contents", dflt: false }, - _headerHeight: { type: "number", description: "height of document header used for displaying title", dflt: 20 }, - _headerFontSize: { type: "number", description: "font size of header of custom notes", dflt: 12 }, - _headerPointerEvents: { type: "string", description: "types of events the header of a custom text document can consume" }, - _panX: { type: "number", description: "horizontal pan location of a freeform view" }, - _panY: { type: "number", description: "vertical pan location of a freeform view" }, - _width: { type: "number", description: "displayed width of a document" }, - _height: { type: "number", description: "displayed height of document" }, - _nativeWidth: { type: "number", description: "native width of document contents (e.g., the pixel width of an image)" }, - _nativeHeight: { type: "number", description: "native height of document contents (e.g., the pixel height of an image)" }, - _dimMagnitude: { type: "number", description: "magnitude of collectionMulti{row,col} element's width or height" }, - _dimUnit: { type: "string", description: "units of collectionMulti{row,col} element's width or height - 'px' or '*' for pixels or relative units" }, - _fitWidth: { type: "boolean", description: "whether document should scale its contents to fit its rendered width or not (e.g., for PDFviews)" } - -} -/*_fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents +class BoolInfo extends FInfo { type?= "boolean"; values?: boolean[] = [true, false]; } +class NumInfo extends FInfo { type?= "number"; values?: number[] = []; } +class StrInfo extends FInfo { type?= "string"; values?: string[] = []; } +class DocInfo extends FInfo { type?= "Doc"; values?: Doc[] = []; } +class DimInfo extends FInfo { type?= "DimUnit"; values?= [DimUnit.Pixel, DimUnit.Ratio]; } +class PEInfo extends FInfo { type?= "pointerEvents"; values?= ["all", "none"]; } +class DAInfo extends FInfo { type?= "dropActionType"; values?= ["alias", "copy", "move", "same", "proto", "none"]; } +type BOOLt = BoolInfo | boolean; +type NUMt = NumInfo | number; +type STRt = StrInfo | string; +type DOCt = DocInfo | Doc; +type DIMt = DimInfo | typeof DimUnit.Pixel | typeof DimUnit.Ratio; +type PEVt = PEInfo | "none" | "all"; +type DROPt = DAInfo | dropActionType; +export class DocumentOptions { + system?: BOOLt = new BoolInfo("is this a system created/owned doc"); + userDoc?: DOCt = new DocInfo("the user doc"); + dropAction?: DROPt = new DAInfo("what should happen to the source document when it's dropped onto this doc "); + childDropAction?: DROPt = new DAInfo("what should happen to the source document when it's dropped onto a child of a collection "); + targetDropAction?: DROPt = new DAInfo("what should happen to the source document when ??? "); + backgroundColor?: STRt = new StrInfo("background color for data doc"); + _backgroundColor?: STRt = new StrInfo("background color for each template layout doc (overrides backgroundColor)", true); + _autoHeight?: BOOLt = new BoolInfo("whether document automatically resizes vertically to display contents", true); + _headerHeight?: NUMt = new NumInfo("height of document header used for displaying title", true); + _headerFontSize?: NUMt = new NumInfo("font size of header of custom notes", true); + _headerPointerEvents?: PEVt = new PEInfo("types of events the header of a custom text document can consume", true); + _panX?: NUMt = new NumInfo("horizontal pan location of a freeform view", true); + _panY?: NUMt = new NumInfo("vertical pan location of a freeform view", true); + _width?: NUMt = new NumInfo("displayed width of a document", true); + _height?: NUMt = new NumInfo("displayed height of document", true); + _nativeWidth?: NUMt = new NumInfo("native width of document contents (e.g., the pixel width of an image)", true); + _nativeHeight?: NUMt = new NumInfo("native height of document contents (e.g., the pixel height of an image)", true); + _dimMagnitude?: NUMt = new NumInfo("magnitude of collectionMulti{row,col} element's width or height", true); + _dimUnit?: DIMt = new DimInfo("units of collectionMulti{row,col} element's width or height - 'px' or '*' for pixels or relative units", true); + _fitWidth?: BOOLt = new BoolInfo("whether document should scale its contents to fit its rendered width or not (e.g., for PDFviews)", true); + _fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents _freeformLOD?: boolean; // whether to use LOD to render a freeform document _showTitle?: string; // field name to display in header (:hover is an optional suffix) _showCaption?: string; // which field to display in the caption area. leave empty to have no caption @@ -281,16 +133,12 @@ let _docOptions: DocumentOptions = { z?: number; author?: string; _hideContextMenu?: boolean; // whether the context menu can be shown - dropAction?: dropActionType; - childDropAction?: dropActionType; - targetDropAction?: dropActionType; layoutKey?: string; type?: string; title?: string; version?: string; // version identifier for a document label?: string; hidden?: boolean; - userDoc?: Doc; // the userDocument toolTip?: string; // tooltip to display on hover style?: string; page?: number; @@ -313,8 +161,6 @@ let _docOptions: DocumentOptions = { targetScriptKey?: string; // where to write a template script (used by collections with click templates which need to target onClick, onDoubleClick, etc) templates?: List; hero?: ImageField; // primary image that best represents a compound document (e.g., for a buxton device document that has multiple images) - backgroundColor?: string | ScriptField; // background color for data doc - _backgroundColor?: string | ScriptField; // background color for each template layout doc ( overrides backgroundColor ) color?: string; // foreground color data doc _color?: string; // foreground color for each template layout doc (overrides color) _clipWidth?: number; // percent transition from before to after in comparisonBox @@ -416,37 +262,34 @@ let _docOptions: DocumentOptions = { useLinkSmallAnchor?: boolean; // whether links to this document should use a miniature linkAnchorBox border?: string; //for searchbox _hovercolor?: string; -}*/ - -class EmptyBox { - public static LayoutString() { - return ""; - } } - export namespace Docs { - export let FieldInfos: Doc | undefined; + const _docOptions = new DocumentOptions(); + export async function setupFieldInfos() { - const fieldDocs = await DocServer.GetRefField("FieldInfos"); - if (fieldDocs instanceof Doc) { - Docs.FieldInfos = fieldDocs; - } else { + return await DocServer.GetRefField("FieldInfos7") as Doc ?? runInAction(() => { - const infos = Docs.FieldInfos = new Doc("FieldInfos", true); - const keys = Object.keys(_docOptions); - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - const options = (_docOptions as any)[key] as dinfo; + const infos = new Doc("FieldInfos7", true); + const keys = Object.keys(new DocumentOptions()); + for (const key of keys) { + const options = (_docOptions as any)[key] as FInfo; const finfo = new Doc(); finfo.name = key; - finfo.default = options.dflt; + switch (options.type) { + case "boolean": finfo.options = new List(options.values as any as boolean[]); break; + case "number": finfo.options = new List(options.values as any as number[]); break; + case "Doc": finfo.options = new List(options.values as any as Doc[]); break; + default: // string, pointerEvents, dimUnit, dropActionType + finfo.options = new List(options.values as any as string[]); break; + } + finfo.layoutField = options.layoutField; finfo.description = options.description; finfo.type = options.type; infos[key] = finfo; } + return infos; }); - } } export let newAccount: boolean = false; @@ -682,7 +525,7 @@ export namespace Docs { // whatever options pertain to this specific prototype const options = { title, type, baseProto: true, ...defaultOptions, ...(template.options || {}) }; options.layout = layout.view?.LayoutString(layout.dataField); - const doc = Doc.assign(new Doc(prototypeId, true), { system: true, layoutKey: "layout", ...options }); + const doc = Doc.assign(new Doc(prototypeId, true), { system: true, layoutKey: "layout", ...options } as any); doc.data = template.data; doc.layout_keyValue = KeyValueBox.LayoutString(""); return doc; @@ -847,7 +690,7 @@ export namespace Docs { if (value !== undefined) { deleg[fieldKey] = value; } - return Doc.assign(deleg, options); + return Doc.assign(deleg, options as any); } export function ImageDocument(url: string, options: DocumentOptions = {}) { @@ -964,8 +807,8 @@ export namespace Docs { I.x = options.x; I.y = options.y; I._backgroundColor = "transparent"; - I._width = options._width; - I._height = options._height; + I._width = options._width as number; + I._height = options._height as number; I._fontFamily = "cursive"; I.author = Doc.CurrentUserEmail; I.rotation = 0; @@ -1337,7 +1180,7 @@ export namespace DocUtils { if (type.indexOf("video") !== -1) { ctor = Docs.Create.VideoDocument; if (!options._width) options._width = 600; - if (!options._height) options._height = options._width * 2 / 3; + if (!options._height) options._height = (options._width as number) * 2 / 3; } if (type.indexOf("audio") !== -1) { ctor = Docs.Create.AudioDocument; @@ -1345,7 +1188,7 @@ export namespace DocUtils { if (type.indexOf("pdf") !== -1) { ctor = Docs.Create.PdfDocument; if (!options._width) options._width = 400; - if (!options._height) options._height = options._width * 1200 / 927; + if (!options._height) options._height = (options._width as number) * 1200 / 927; } if (type.indexOf("html") !== -1) { if (path.includes(window.location.hostname)) { @@ -1356,8 +1199,8 @@ export namespace DocUtils { const alias = Doc.MakeAlias(field); alias.x = options.x || 0; alias.y = options.y || 0; - alias._width = options._width || 300; - alias._height = options._height || options._width || 300; + alias._width = (options._width as number) || 300; + alias._height = (options._height as number) || (options._width as number) || 300; return alias; } return undefined; diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index dcaf61fea..9a38c56e7 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1050,7 +1050,7 @@ export class CurrentUserUtils { // } // }); setTimeout(() => DocServer.UPDATE_SERVER_CACHE(), 2500); - doc.fieldInfos = Docs.FieldInfos; + doc.fieldInfos = await Docs.setupFieldInfos(); return doc; } @@ -1070,7 +1070,6 @@ export class CurrentUserUtils { } public static async loadUserDocument(id: string) { - await Docs.setupFieldInfos(); this.curr_id = id; await rp.get(Utils.prepend("/getUserDocumentIds")).then(ids => { const { userDocumentId, sharingDocumentId, linkDatabaseId } = JSON.parse(ids); diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index e1fbea76e..15b98467c 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -276,6 +276,6 @@ export class LightboxTourBtn extends React.Component { this.props.stepInto(); }, StrCast(this.props.tourMap()?.lastElement()?.TourMap) - ) + ); } } \ No newline at end of file diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 3f8794665..68ca93f43 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -382,7 +382,8 @@ export class TabMinimapView extends React.Component { } } @computed get renderBounds() { - const bounds = this.props.tabView()?.ComponentView?.freeformData?.(true)?.bounds; + const compView = this.props.tabView()?.ComponentView as CollectionFreeFormView; + const bounds = compView?.freeformData?.(true)?.bounds; if (!bounds) return undefined; const xbounds = bounds.r - bounds.x; const ybounds = bounds.b - bounds.y; diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 513ef4015..6975c24d1 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -499,7 +499,7 @@ export class TreeView extends React.Component { [{ script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" }] : Doc.IsSystem(this.doc) ? [] : this.fileSysMode && this.doc === Doc.GetProto(this.doc) ? [{ script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" }] : - [{ script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }]; + [{ script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }] truncateTitleWidth = () => NumCast(this.props.treeView.props.Document.treeViewTruncateTitleWidth, this.props.panelWidth()); onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick)); onChildDoubleClick = () => (!this.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick); -- cgit v1.2.3-70-g09d2 From fce6c26e2f62ffc21702a2edc64e0ee00828825e Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 26 Feb 2021 12:35:35 -0500 Subject: minimal cleanup of standard fields. fix to error thrown in document buttonbar --- src/client/documents/Documents.ts | 3 --- src/client/util/CurrentUserUtils.ts | 24 ++++++++++++------------ src/client/views/DocumentButtonBar.tsx | 6 +++--- src/fields/ScriptField.ts | 4 ++-- 4 files changed, 17 insertions(+), 20 deletions(-) (limited to 'src/client/views') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index de08040e2..d8a77bfdb 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -90,7 +90,6 @@ type PEVt = PEInfo | "none" | "all"; type DROPt = DAInfo | dropActionType; export class DocumentOptions { system?: BOOLt = new BoolInfo("is this a system created/owned doc"); - userDoc?: DOCt = new DocInfo("the user doc"); dropAction?: DROPt = new DAInfo("what should happen to the source document when it's dropped onto this doc "); childDropAction?: DROPt = new DAInfo("what should happen to the source document when it's dropped onto a child of a collection "); targetDropAction?: DROPt = new DAInfo("what should happen to the source document when ??? "); @@ -140,8 +139,6 @@ export class DocumentOptions { label?: string; hidden?: boolean; toolTip?: string; // tooltip to display on hover - style?: string; - page?: number; dontUndo?: boolean; // whether button clicks should be undoable (this is set to true for Undo/Redo/and sidebar buttons that open the siebar panel) description?: string; // added for links _viewScale?: number; diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 9a38c56e7..eef2236b5 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -224,8 +224,8 @@ export class CurrentUserUtils { if (doc["template-buttons"] === undefined) { doc["template-buttons"] = new PrefetchProxy(Docs.Create.MasonryDocument(requiredTypes, { title: "Advanced Item Prototypes", _xMargin: 0, _showTitle: "title", - hidden: ComputedField.MakeFunction("self.userDoc.noviceMode") as any, - userDoc: doc, _stayInCollection: true, _hideContextMenu: true, + hidden: ComputedField.MakeFunction("IsNoviceMode()") as any, + _stayInCollection: true, _hideContextMenu: true, _autoHeight: true, _width: 500, _columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true })); @@ -242,23 +242,23 @@ export class CurrentUserUtils { // setup the different note type skins static setupNoteTemplates(doc: Doc) { if (doc["template-note-Note"] === undefined) { - const noteView = Docs.Create.TextDocument("", { title: "text", style: "Note", isTemplateDoc: true, backgroundColor: "yellow", system: true }); + const noteView = Docs.Create.TextDocument("", { title: "text", isTemplateDoc: true, backgroundColor: "yellow", system: true }); noteView.isTemplateDoc = makeTemplate(noteView, true, "Note"); doc["template-note-Note"] = new PrefetchProxy(noteView); } - if (doc["template-note-Idea"] === undefined) { - const noteView = Docs.Create.TextDocument("", { title: "text", style: "Idea", backgroundColor: "pink", system: true }); + if (true || doc["template-note-Idea"] === undefined) { + const noteView = Docs.Create.TextDocument("", { title: "text", backgroundColor: "pink", system: true }); noteView.isTemplateDoc = makeTemplate(noteView, true, "Idea"); doc["template-note-Idea"] = new PrefetchProxy(noteView); } if (doc["template-note-Topic"] === undefined) { - const noteView = Docs.Create.TextDocument("", { title: "text", style: "Topic", backgroundColor: "lightblue", system: true }); + const noteView = Docs.Create.TextDocument("", { title: "text", backgroundColor: "lightblue", system: true }); noteView.isTemplateDoc = makeTemplate(noteView, true, "Topic"); doc["template-note-Topic"] = new PrefetchProxy(noteView); } if (doc["template-note-Todo"] === undefined) { const noteView = Docs.Create.TextDocument("", { - title: "text", style: "Todo", backgroundColor: "orange", _autoHeight: false, _height: 100, _showCaption: "caption", + title: "text", backgroundColor: "orange", _autoHeight: false, _height: 100, _showCaption: "caption", layout: FormattedTextBox.LayoutString("Todo"), caption: RichTextField.DashField("taskStatus"), system: true }); noteView.isTemplateDoc = makeTemplate(noteView, true, "Todo"); @@ -498,8 +498,7 @@ export class CurrentUserUtils { _stayInCollection: true, dragFactory, clickFactory, - userDoc: noviceMode ? undefined as any : doc, - hidden: noviceMode ? undefined as any : ComputedField.MakeFunction("self.userDoc.noviceMode"), + hidden: ComputedField.MakeFunction("IsNoviceMode()") as any, system: true })); @@ -560,9 +559,8 @@ export class CurrentUserUtils { watchedDocuments, onClick: ScriptField.MakeScript(click, { scriptContext: "any" }) })); - const userDoc = menuBtns[menuBtns.length - 1]; - userDoc.userDoc = doc; - userDoc.hidden = ComputedField.MakeFunction("self.userDoc.noviceMode"); + // hack -- last button is assumed to be the userDoc + menuBtns[menuBtns.length - 1].hidden = ComputedField.MakeFunction("IsNoviceMode()"); doc.menuStack = new PrefetchProxy(Docs.Create.StackingDocument(menuBtns, { title: "menuItemPanel", @@ -1235,6 +1233,8 @@ Scripting.addGlobal(function openDragFactory(dragFactory: Doc) { view && SelectionManager.SelectView(view, false); } }); +Scripting.addGlobal(function IsNoviceMode() { return Doc.UserDoc().noviceMode; }, + "is Dash in novice mode"); Scripting.addGlobal(function snapshotDashboard() { CurrentUserUtils.snapshotDashboard(Doc.UserDoc()); }, "creates a snapshot copy of a dashboard"); Scripting.addGlobal(function createNewDashboard() { return CurrentUserUtils.createNewDashboard(Doc.UserDoc()); }, diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 209e750d6..a9cd7b4a9 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -312,7 +312,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV return false; } - _ref = React.createRef(); + _ref = React.createRef(); @observable _tooltipOpen: boolean = false; @computed get templateButton() { @@ -321,11 +321,11 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV return !view0 ? (null) : Tap to Customize Layout. Drag an embeddable alias} open={this._tooltipOpen} onClose={action(() => this._tooltipOpen = false)} placement="bottom">
!(this._ref.current as any as HTMLElement)?.getBoundingClientRect().width && (this._tooltipOpen = true))} > + onPointerEnter={action(() => !this._ref.current?.getBoundingClientRect().width && (this._tooltipOpen = true))} > this._aliasDown = true)} onClose={action(() => this._aliasDown = false)} content={!this._aliasDown ? (null) : - v).map(v => v as DocumentView)} />}> +
v).map(v => v as DocumentView)} />
}>
{}
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts index c949e0791..9345ecde5 100644 --- a/src/fields/ScriptField.ts +++ b/src/fields/ScriptField.ts @@ -55,8 +55,8 @@ async function deserializeScript(script: ScriptField) { if (script.script.originalScript === 'convertToButtons(dragData)') { return (script as any).script = (ScriptField.ConvertToButtons ?? (ScriptField.ConvertToButtons = ComputedField.MakeFunction('convertToButtons(dragData)', { dragData: "DocumentDragData" })))?.script; } - if (script.script.originalScript === 'self.userDoc.noviceMode') { - return (script as any).script = (ScriptField.NoviceMode ?? (ScriptField.NoviceMode = ComputedField.MakeFunction('self.userDoc.noviceMode')))?.script; + if (script.script.originalScript === 'IsNoviceMode()') { + return (script as any).script = (ScriptField.NoviceMode ?? (ScriptField.NoviceMode = ComputedField.MakeFunction('IsNoviceMode()')))?.script; } if (script.script.originalScript === `selectMainMenu(self)`) { return (script as any).script = (ScriptField.SelectMenu ?? (ScriptField.SelectMenu = ComputedField.MakeFunction('selectMainMenu(self)')))?.script; -- cgit v1.2.3-70-g09d2 From daa1e3ddf585f5fe237c100504130a3eae204252 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 26 Feb 2021 15:12:28 -0500 Subject: fixed serialization error handling to not kill Dash - bad list items prevented tabs from being created. cleaned up document fields a little more - switched layers to _layerTags, got rid of a couple unused fields. --- src/client/documents/Documents.ts | 51 ++++++++++------------ src/client/util/CurrentUserUtils.ts | 49 ++++++++++----------- src/client/util/SerializationHelper.ts | 10 +++-- src/client/views/MainView.tsx | 6 +-- src/client/views/PropertiesButtons.tsx | 8 ++-- src/client/views/StyleProvider.tsx | 12 ++--- .../collectionFreeForm/CollectionFreeFormView.tsx | 10 ++--- .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- .../collectionGrid/CollectionGridView.tsx | 2 +- src/client/views/nodes/DocumentLinksButton.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 12 ++--- src/client/views/nodes/LinkAnchorBox.tsx | 2 +- src/fields/documentSchemas.ts | 3 +- src/fields/util.ts | 1 - src/server/database.ts | 4 +- src/server/websocket.ts | 6 ++- 16 files changed, 91 insertions(+), 89 deletions(-) (limited to 'src/client/views') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index d8a77bfdb..7a32596b0 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -109,15 +109,26 @@ export class DocumentOptions { _dimUnit?: DIMt = new DimInfo("units of collectionMulti{row,col} element's width or height - 'px' or '*' for pixels or relative units", true); _fitWidth?: BOOLt = new BoolInfo("whether document should scale its contents to fit its rendered width or not (e.g., for PDFviews)", true); _fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents + color?: string; // foreground color data doc + _color?: string; // foreground color for each template layout doc (overrides color) + _clipWidth?: number; // percent transition from before to after in comparisonBox + _lockedPosition?: boolean; // lock the x,y coordinates of the document so that it can't be dragged + _lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed _freeformLOD?: boolean; // whether to use LOD to render a freeform document _showTitle?: string; // field name to display in header (:hover is an optional suffix) _showCaption?: string; // which field to display in the caption area. leave empty to have no caption _scrollTop?: number; // scroll location for pdfs _noAutoscroll?: boolean;// whether collections autoscroll when this item is dragged _chromeStatus?: string; + _layerTags?: List; // layer tags a document has (used for tab filtering "layers" in document tab) _searchDoc?: boolean; // is this a search document (used to change UI for search results in schema view) + _stayInCollection?: boolean;// whether the document should remain in its collection when someone tries to drag and drop it elsewhere + _raiseWhenDragged?: boolean; // whether a document is brought to front when dragged. + _hideContextMenu?: boolean; // whether the context menu can be shown _viewType?: string; // sub type of a collection _gridGap?: number; // gap between items in masonry view + _viewScale?: number; // how much a freeform view has been scaled (zoomed) + _overflow?: string; // set overflow behavior _xMargin?: number; // gap between left edge of document and start of masonry/stacking layouts _yMargin?: number; // gap between top edge of dcoument and start of masonry/stacking layouts _xPadding?: number; @@ -125,13 +136,23 @@ export class DocumentOptions { _itemIndex?: number; // which item index the carousel viewer is showing _showSidebar?: boolean; //whether an annotationsidebar should be displayed for text docuemnts _singleLine?: boolean; // whether text document is restricted to a single line (carriage returns make new document) + _columnWidth?: number; + _columnsHideIfEmpty?: boolean; // whether stacking view column headings should be hidden + _fontSize?: string; + _fontWeight?: number; + _fontFamily?: string; + _curPage?: number; + _currentTimecode?: number; // the current timecode of a time-based document (e.g., current time of a video) value is in seconds + _currentFrame?: number; // the current frame of a frame-based collection (e.g., progressive slide) + _timecodeToShow?: number; // the time that a document should be displayed (e.g., when an annotation shows up as a video plays) + _timecodeToHide?: number; // the time that a document should be hidden + _timelineLabel?: boolean; // whether the document exists on a timeline "_carousel-caption-xMargin"?: number; "_carousel-caption-yMargin"?: number; x?: number; y?: number; z?: number; author?: string; - _hideContextMenu?: boolean; // whether the context menu can be shown layoutKey?: string; type?: string; title?: string; @@ -141,8 +162,6 @@ export class DocumentOptions { toolTip?: string; // tooltip to display on hover dontUndo?: boolean; // whether button clicks should be undoable (this is set to true for Undo/Redo/and sidebar buttons that open the siebar panel) description?: string; // added for links - _viewScale?: number; - _overflow?: string; forceActive?: boolean; layout?: string | Doc; // default layout string for a document contentPointerEvents?: string; // pointer events allowed for content of a document view. eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents @@ -151,37 +170,19 @@ export class DocumentOptions { childLayoutString?: string; // template string for collection to use to render its children hideLinkButton?: boolean; // whether the blue link counter button should be hidden hideAllLinks?: boolean; // whether all individual blue anchor dots should be hidden - _columnsHideIfEmpty?: boolean; // whether stacking view column headings should be hidden isTemplateForField?: string; // the field key for which the containing document is a rendering template isTemplateDoc?: boolean; watchedDocuments?: Doc; // list of documents to "watch" in an icon doc to display a badge targetScriptKey?: string; // where to write a template script (used by collections with click templates which need to target onClick, onDoubleClick, etc) templates?: List; hero?: ImageField; // primary image that best represents a compound document (e.g., for a buxton device document that has multiple images) - color?: string; // foreground color data doc - _color?: string; // foreground color for each template layout doc (overrides color) - _clipWidth?: number; // percent transition from before to after in comparisonBox caption?: RichTextField; ignoreClick?: boolean; - lockedPosition?: boolean; // lock the x,y coordinates of the document so that it can't be dragged - _lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed isAnnotating?: boolean; // whether we web document is annotation mode where links can't be clicked to allow annotations to be created opacity?: number; defaultBackgroundColor?: string; - _layers?: List; - _raiseWhenDragged?: boolean; // whether a document is brought to front when dragged. isLinkButton?: boolean; isFolder?: boolean; - _columnWidth?: number; - _fontSize?: string; - _fontWeight?: number; - _fontFamily?: string; - _curPage?: number; - _currentTimecode?: number; // the current timecode of a time-based document (e.g., current time of a video) value is in seconds - _currentFrame?: number; // the current frame of a frame-based collection (e.g., progressive slide) - _timecodeToShow?: number; // the time that a document should be displayed (e.g., when an annotation shows up as a video plays) - _timecodeToHide?: number; // the time that a document should be hidden - _timelineLabel?: boolean; // whether the document exists on a timeline lastFrame?: number; // the last frame of a frame-based collection (e.g., progressive slide) activeFrame?: number; // the active frame of a document in a frame base collection appearFrame?: number; // the frame in which the document appears @@ -230,7 +231,6 @@ export class DocumentOptions { searchFileTypes?: List; // file types allowed in a search query strokeWidth?: number; cloneFieldFilter?: List; // fields not to copy when the document is cloned - _stayInCollection?: boolean;// whether the document should remain in its collection when someone tries to drag and drop it elsewhere freezeChildren?: string; // whether children are now allowed to be added and or removed from a collection treeViewPreventOpen?: boolean; // ignores the treeViewOpen Doc flag which allows a treeViewItem's expand/collapse state to be independent of other views of the same document in the tree view treeViewHideTitle?: boolean; // whether to hide the top document title of a tree view @@ -246,16 +246,13 @@ export class DocumentOptions { sidebarColor?: string; // background color of text sidebar sidebarViewType?: string; // collection type of text sidebar limitHeight?: number; // maximum height for newly created (eg, from pasting) text documents - // [key: string]: Opt; - pointerHack?: boolean; // for buttons, allows onClick handler to fire onPointerDown textTransform?: string; // is linear view expanded letterSpacing?: string; // is linear view expanded flexDirection?: "unset" | "row" | "column" | "row-reverse" | "column-reverse"; - selectedIndex?: number; + selectedIndex?: number; // which item in a linear view has been selected using the "thumb doc" ui syntaxColor?: string; // can be applied to text for syntax highlighting all matches in the text searchQuery?: string; // for quersyBox linearViewIsExpanded?: boolean; // is linear view expanded - isLabel?: boolean; // whether the document is a label or not (video / audio) useLinkSmallAnchor?: boolean; // whether links to this document should use a miniature linkAnchorBox border?: string; //for searchbox _hovercolor?: string; @@ -769,7 +766,7 @@ export namespace Docs { const doc = InstanceFromProto(Prototypes.get(DocumentType.LINK), undefined, { dontRegisterChildViews: true, isLinkButton: true, treeViewHideTitle: true, backgroundColor: "lightblue", // lightblue is default color for linking dot and link documents text comment area - treeViewExpandedView: "fields", removeDropProperties: new List(["_layers", "isLinkButton"]), ...options + treeViewExpandedView: "fields", removeDropProperties: new List(["_layerTags", "isLinkButton"]), ...options }, id); const linkDocProto = Doc.GetProto(doc); linkDocProto.treeViewOpen = true;// setting this in the instance creator would set it on the view document. diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index eef2236b5..ca5d4d371 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -226,7 +226,7 @@ export class CurrentUserUtils { title: "Advanced Item Prototypes", _xMargin: 0, _showTitle: "title", hidden: ComputedField.MakeFunction("IsNoviceMode()") as any, _stayInCollection: true, _hideContextMenu: true, - _autoHeight: true, _width: 500, _columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", + _autoHeight: true, _width: 500, _columnWidth: 35, ignoreClick: true, _lockedPosition: true, _chromeStatus: "disabled", dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true })); } else { @@ -246,7 +246,7 @@ export class CurrentUserUtils { noteView.isTemplateDoc = makeTemplate(noteView, true, "Note"); doc["template-note-Note"] = new PrefetchProxy(noteView); } - if (true || doc["template-note-Idea"] === undefined) { + if (doc["template-note-Idea"] === undefined) { const noteView = Docs.Create.TextDocument("", { title: "text", backgroundColor: "pink", system: true }); noteView.isTemplateDoc = makeTemplate(noteView, true, "Idea"); doc["template-note-Idea"] = new PrefetchProxy(noteView); @@ -505,7 +505,7 @@ export class CurrentUserUtils { if (dragCreatorSet === undefined) { doc.myItemCreators = new PrefetchProxy(Docs.Create.MasonryDocument(creatorBtns, { title: "Basic Item Creators", _showTitle: "title", _xMargin: 0, _stayInCollection: true, _hideContextMenu: true, - _autoHeight: true, _width: 500, _columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", + _autoHeight: true, _width: 500, _columnWidth: 35, ignoreClick: true, _lockedPosition: true, _chromeStatus: "disabled", dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true })); } else { @@ -534,7 +534,7 @@ export class CurrentUserUtils { if (doc.mySearchPanelDoc === undefined) { doc.mySearchPanelDoc = new PrefetchProxy(Docs.Create.SearchDocument({ _width: 500, _height: 300, backgroundColor: "dimGray", ignoreClick: true, _searchDoc: true, - childDropAction: "alias", lockedPosition: true, _viewType: CollectionViewType.Schema, _chromeStatus: "disabled", title: "sidebar search stack", system: true + childDropAction: "alias", _lockedPosition: true, _viewType: CollectionViewType.Schema, _chromeStatus: "disabled", title: "sidebar search stack", system: true })) as any as Doc; } } @@ -569,7 +569,7 @@ export class CurrentUserUtils { _backgroundColor: "black", ignoreClick: true, _gridGap: 0, _yMargin: 0, - _yPadding: 0, _xMargin: 0, _autoHeight: false, _width: 60, _columnWidth: 60, lockedPosition: true, _chromeStatus: "disabled", system: true + _yPadding: 0, _xMargin: 0, _autoHeight: false, _width: 60, _columnWidth: 60, _lockedPosition: true, _chromeStatus: "disabled", system: true })); } // this resets all sidebar buttons to being deactivated @@ -602,7 +602,7 @@ export class CurrentUserUtils { // Sets up mobileMenu stacking document static setupMobileMenu() { const menu = new PrefetchProxy(Docs.Create.StackingDocument(this.setupMobileButtons(), { - _width: 980, ignoreClick: true, lockedPosition: false, _chromeStatus: "disabled", title: "home", _yMargin: 100, system: true + _width: 980, ignoreClick: true, _lockedPosition: false, _chromeStatus: "disabled", title: "home", _yMargin: 100, system: true })); return menu; } @@ -621,7 +621,7 @@ export class CurrentUserUtils { return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data => this.mobileButton({ title: data.title, - lockedPosition: true, + _lockedPosition: true, onClick: data.click ? ScriptField.MakeScript(data.click) : undefined, _backgroundColor: data.backgroundColor, system: true }, @@ -670,7 +670,7 @@ export class CurrentUserUtils { onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined, clipboard: data.clipboard, onPointerUp: data.pointerUp ? ScriptField.MakeScript(data.pointerUp) : undefined, onPointerDown: data.pointerDown ? ScriptField.MakeScript(data.pointerDown) : undefined, - ischecked: data.ischecked ? ComputedField.MakeFunction(data.ischecked) : undefined, activeInkPen: data.activeInkPen, pointerHack: true, + ischecked: data.ischecked ? ComputedField.MakeFunction(data.ischecked) : undefined, activeInkPen: data.activeInkPen, backgroundColor: data.backgroundColor, removeDropProperties: new List(["dropAction"]), dragFactory: data.dragFactory, system: true })); } @@ -678,7 +678,7 @@ export class CurrentUserUtils { static setupThumbDoc(userDoc: Doc) { if (!userDoc.thumbDoc) { const thumbDoc = Docs.Create.LinearDocument(CurrentUserUtils.setupThumbButtons(userDoc), { - _width: 100, _height: 50, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "buttons", + _width: 100, _height: 50, ignoreClick: true, _lockedPosition: true, _chromeStatus: "disabled", title: "buttons", _autoHeight: true, _yMargin: 5, linearViewIsExpanded: true, backgroundColor: "white", system: true }); thumbDoc.inkToTextDoc = Docs.Create.LinearDocument([], { @@ -696,13 +696,13 @@ export class CurrentUserUtils { static setupMobileUploadDoc(userDoc: Doc) { // const addButton = Docs.Create.FontIconDocument({ onDragStart: ScriptField.MakeScript('addWebToMobileUpload()'), title: "Add Web Doc to Upload Collection", icon: "plus", backgroundColor: "black" }) const webDoc = Docs.Create.WebDocument("https://www.britannica.com/biography/Miles-Davis", { - title: "Upload Images From the Web", _chromeStatus: "enabled", lockedPosition: true, system: true + title: "Upload Images From the Web", _chromeStatus: "enabled", _lockedPosition: true, system: true }); const uploadDoc = Docs.Create.StackingDocument([], { - title: "Mobile Upload Collection", backgroundColor: "white", lockedPosition: true, system: true + title: "Mobile Upload Collection", backgroundColor: "white", _lockedPosition: true, system: true }); return Docs.Create.StackingDocument([webDoc, uploadDoc], { - _width: screen.width, lockedPosition: true, _chromeStatus: "disabled", title: "Upload", _autoHeight: true, _yMargin: 80, backgroundColor: "lightgray", system: true + _width: screen.width, _lockedPosition: true, _chromeStatus: "disabled", title: "Upload", _autoHeight: true, _yMargin: 80, backgroundColor: "lightgray", system: true }); } @@ -722,7 +722,7 @@ export class CurrentUserUtils { if (doc.myCreators === undefined) { doc.myCreators = new PrefetchProxy(Docs.Create.StackingDocument([creatorBtns, templateBtns], { title: "all Creators", _yMargin: 0, _autoHeight: true, _xMargin: 0, - _width: 500, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", system: true + _width: 500, ignoreClick: true, _lockedPosition: true, _chromeStatus: "disabled", system: true })); } // setup a color picker @@ -735,7 +735,7 @@ export class CurrentUserUtils { if (doc.myTools === undefined) { const toolsStack = new PrefetchProxy(Docs.Create.StackingDocument([doc.myCreators as Doc, doc.myColorPicker as Doc], { - title: "My Tools", _width: 500, _yMargin: 20, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", forceActive: true, system: true, _stayInCollection: true, _hideContextMenu: true, + title: "My Tools", _width: 500, _yMargin: 20, ignoreClick: true, _lockedPosition: true, _chromeStatus: "disabled", forceActive: true, system: true, _stayInCollection: true, _hideContextMenu: true, })) as any as Doc; doc.myTools = toolsStack; @@ -750,7 +750,7 @@ export class CurrentUserUtils { title: "My Dashboards", _height: 400, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, - lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })); const newDashboard = ScriptField.MakeScript(`createNewDashboard(Doc.UserDoc())`); (doc.myDashboards as any as Doc).contextMenuScripts = new List([newDashboard!]); @@ -766,7 +766,7 @@ export class CurrentUserUtils { title: "My Presentations", _height: 100, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, - lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })); const newPresentations = ScriptField.MakeScript(`createNewPresentation()`); (doc.myPresentations as any as Doc).contextMenuScripts = new List([newPresentations!]); @@ -786,7 +786,7 @@ export class CurrentUserUtils { treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, isFolder: true, treeViewType: "fileSystem", - lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })); } return doc.myFilesystem as any as Doc; @@ -794,13 +794,12 @@ export class CurrentUserUtils { static setupRecentlyClosedDocs(doc: Doc) { // setup Recently Closed library item - doc.myRecentlyClosedDocs === undefined; if (doc.myRecentlyClosedDocs === undefined) { doc.myRecentlyClosedDocs = new PrefetchProxy(Docs.Create.TreeDocument([], { title: "Recently Closed", _height: 500, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, - lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })); const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([])`); (doc.myRecentlyClosedDocs as any as Doc).contextMenuScripts = new List([clearAll!]); @@ -815,7 +814,7 @@ export class CurrentUserUtils { title: "FilterDoc", _height: 500, treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "none", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, - lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })); } const clearAll = ScriptField.MakeScript(`getProto(self).data = new List([]); scriptContext._docFilters = scriptContext._docRangeFilters = undefined;`, { scriptContext: Doc.name }); @@ -831,7 +830,7 @@ export class CurrentUserUtils { doc.myUserDoc = new PrefetchProxy(Docs.Create.TreeDocument([doc], { treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, title: "My UserDoc", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, - lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })) as any as Doc; } } @@ -861,7 +860,7 @@ export class CurrentUserUtils { static blist = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.LinearDocument(docs, { ...opts, _gridGap: 5, _xMargin: 5, _yMargin: 5, _height: 42, _width: 100, boxShadow: "0 0", forceActive: true, dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), - backgroundColor: "black", treeViewPreventOpen: true, lockedPosition: true, _chromeStatus: "disabled", linearViewIsExpanded: true, system: true + backgroundColor: "black", treeViewPreventOpen: true, _lockedPosition: true, _chromeStatus: "disabled", linearViewIsExpanded: true, system: true })) as any as Doc static ficon = (opts: DocumentOptions) => new PrefetchProxy(Docs.Create.FontIconDocument({ @@ -915,7 +914,7 @@ export class CurrentUserUtils { if (!sharedDocs) { sharedDocs = Docs.Create.StackingDocument([], { title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "none", childLimitHeight: 0, _yMargin: 50, _gridGap: 15, - _showTitle: "title", ignoreClick: true, lockedPosition: true, + _showTitle: "title", ignoreClick: true, _lockedPosition: true, }, sharingDocumentId + "outer", sharingDocumentId); (sharedDocs as Doc)["acl-Public"] = Doc.GetProto(sharedDocs as Doc)["acl-Public"] = SharingPermissions.Add; } @@ -931,13 +930,13 @@ export class CurrentUserUtils { if (doc.myImportDocs === undefined) { doc.myImportDocs = new PrefetchProxy(Docs.Create.StackingDocument([], { title: "My ImportDocuments", forceActive: true, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0, - childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, lockedPosition: true, _chromeStatus: "disabled", system: true + childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, _lockedPosition: true, _chromeStatus: "disabled", system: true })); } if (doc.myImportPanel === undefined) { const uploads = Cast(doc.myImportDocs, Doc, null); const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Import External document", _stayInCollection: true, _hideContextMenu: true, title: "Import", icon: "upload", system: true }); - doc.myImportPanel = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "My ImportPanel", _yMargin: 20, ignoreClick: true, _stayInCollection: true, _hideContextMenu: true, lockedPosition: true, system: true })); + doc.myImportPanel = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "My ImportPanel", _yMargin: 20, ignoreClick: true, _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, system: true })); } } diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts index 00ac6e521..4c3b3f096 100644 --- a/src/client/util/SerializationHelper.ts +++ b/src/client/util/SerializationHelper.ts @@ -22,10 +22,12 @@ export namespace SerializationHelper { return obj; } - serializing++; if (!(obj.constructor.name in reverseMap)) { - throw Error(`type '${obj.constructor.name}' not registered. Make sure you register it using a @Deserializable decorator`); + // throw Error( + console.log("Error: " + `type '${obj.constructor.name}' not registered. Make sure you register it using a @Deserializable decorator`, obj); + return undefined; } + serializing++; const json = serialize(obj); json.__type = reverseMap[obj.constructor.name]; @@ -52,7 +54,9 @@ export namespace SerializationHelper { } if (!(obj.__type in serializationTypes)) { - throw Error(`type '${obj.__type}' not registered. Make sure you register it using a @Deserializable decorator`); + // throw Error( + console.log(`type '${obj.__type}' not registered. Make sure you register it using a @Deserializable decorator`); + return undefined; } const type = serializationTypes[obj.__type]; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 314922df8..d17668ea7 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -228,7 +228,7 @@ export class MainView extends React.Component { createNewPresentation = async () => { if (!await this.userDoc.myPresentations) { this.userDoc.myPresentations = new PrefetchProxy(Docs.Create.TreeDocument([], { - title: "PRESENTATION TRAILS", _height: 100, forceActive: true, boxShadow: "0 0", lockedPosition: true, treeViewOpen: true, system: true + title: "PRESENTATION TRAILS", _height: 100, forceActive: true, boxShadow: "0 0", _lockedPosition: true, treeViewOpen: true, system: true })); } const pres = Docs.Create.PresDocument(new List(), @@ -319,8 +319,8 @@ export class MainView extends React.Component {
toggleField(e, doc, "hidden")}>
-
toggleField(e, doc, "lockedPosition")}> - +
toggleField(e, doc, "_lockedPosition")}> +
; } diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 8ad5f3f2b..e9963bce9 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -194,12 +194,12 @@ export class PropertiesButtons extends React.Component<{}, {}> { get lockButton() { const targetDoc = this.selectedDoc; return !targetDoc ? (null) : {`${this.selectedDoc?.lockedPosition ? "Unlock" : "Lock"} Position`}
} placement="top"> + title={
{`${this.selectedDoc?._lockedPosition ? "Unlock" : "Lock"} Position`}
} placement="top">
-
+
+ color={this.selectedDoc?._lockedPosition ? "black" : "white"} + icon={this.selectedDoc?._lockedPosition ? "unlock" : "lock"} />
Position
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 73a82d7ab..69a1e4db2 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -44,9 +44,9 @@ function darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkSc function toggleBackground(doc: Doc) { UndoManager.RunInBatch(() => runInAction(() => { - const layers = StrListCast(doc.layers); + const layers = StrListCast(doc._layerTags); if (!layers.includes(StyleLayers.Background)) { - if (!layers.length) doc.layers = new List([StyleLayers.Background]); + if (!layers.length) doc._layerTags = new List([StyleLayers.Background]); else layers.push(StyleLayers.Background); } else layers.splice(layers.indexOf(StyleLayers.Background), 1); @@ -65,7 +65,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt StrListCast(doc?.layers).includes(StyleLayers.Background); + const isBackground = () => StrListCast(doc?._layerTags).includes(StyleLayers.Background); const backgroundCol = () => props?.styleProvider?.(doc, props, StyleProp.BackgroundColor); const opacity = () => props?.styleProvider?.(doc, props, StyleProp.Opacity); @@ -184,15 +184,15 @@ export function DefaultLayerProvider(thisDoc: Doc) { if (assign) { const activeLayer = StrCast(thisDoc?.activeLayer); if (activeLayer) { - const layers = Cast(doc.layers, listSpec("string"), []); + const layers = Cast(doc._layerTags, listSpec("string"), []); if (layers.length && !layers.includes(activeLayer)) layers.push(activeLayer); - else if (!layers.length) doc.layers = new List([activeLayer]); + else if (!layers.length) doc._layerTags = new List([activeLayer]); if (activeLayer === "red" || activeLayer === "green" || activeLayer === "blue") doc._backgroundColor = activeLayer; } return true; } else { if (Doc.AreProtosEqual(doc, thisDoc)) return true; - const layers = StrListCast(doc.layers); + const layers = StrListCast(doc._layerTags); if (!layers.length && !thisDoc?.activeLayer) return true; if (layers.includes(StrCast(thisDoc?.activeLayer))) return true; return false; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 4040362d8..02f148eb0 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -264,7 +264,7 @@ export class CollectionFreeFormView extends CollectionSubView s.backgroundColor); // override the cluster color with an explicitly set color on a non-background document. then override that with an explicitly set color on a background document - set?.filter(s => !StrListCast(s.layers).includes(StyleLayers.Background)).map(s => styleProp = StrCast(s.backgroundColor)); - set?.filter(s => StrListCast(s.layers).includes(StyleLayers.Background)).map(s => styleProp = StrCast(s.backgroundColor)); + set?.filter(s => !StrListCast(s._layerTags).includes(StyleLayers.Background)).map(s => styleProp = StrCast(s.backgroundColor)); + set?.filter(s => StrListCast(s._layerTags).includes(StyleLayers.Background)).map(s => styleProp = StrCast(s.backgroundColor)); } } //else if (doc && NumCast(doc.group, -1) !== -1) styleProp = "gray"; return styleProp; @@ -869,7 +869,7 @@ export class CollectionFreeFormView extends CollectionSubView { - if (sendToBack || StrListCast(doc.layers).includes(StyleLayers.Background)) { + if (sendToBack || StrListCast(doc._layerTags).includes(StyleLayers.Background)) { doc.zIndex = 0; } else if (doc.isInkMask) { doc.zIndex = 5000; @@ -1363,7 +1363,7 @@ export class CollectionFreeFormView extends CollectionSubView intersectRect(docDims(doc), rect); const otherBounds = { left: this.panX(), top: this.panY(), width: Math.abs(size[0]), height: Math.abs(size[1]) }; - let snappableDocs = activeDocs.filter(doc => !StrListCast(doc.layers).includes(StyleLayers.Background) && doc.z === undefined && isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to + let snappableDocs = activeDocs.filter(doc => !StrListCast(doc._layerTags).includes(StyleLayers.Background) && doc.z === undefined && isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to !snappableDocs.length && (snappableDocs = activeDocs.filter(doc => doc.z === undefined && isDocInView(doc, selRect))); // if not, see if there are background docs to snap to !snappableDocs.length && (snappableDocs = activeDocs.filter(doc => doc.z !== undefined && isDocInView(doc, otherBounds))); // if not, then why not snap to floating docs diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 34ddf6ed2..ff6c2860a 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -363,7 +363,7 @@ export class MarqueeView extends React.Component(layers); + newCollection._layerTags = new List(layers); newCollection._width = this.Bounds.width; newCollection._height = this.Bounds.height; newCollection._isGroup = makeGroup; diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index 58db080ad..e2feff5ed 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -235,7 +235,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { i, y, h, x: x + w > this.numCols ? 0 : x, // handles wrapping around of nodes when numCols decreases w: Math.min(w, this.numCols), // reduces width if greater than numCols - static: BoolCast(this.childLayoutPairs.find(({ layout }) => layout[Id] === i)?.layout.lockedPosition, false) // checks if the lock position item has been selected in the context menu + static: BoolCast(this.childLayoutPairs.find(({ layout }) => layout[Id] === i)?.layout._lockedPosition, false) // checks if the lock position item has been selected in the context menu })) : this.savedLayoutList.map((layout, index) => { Object.assign(layout, this.unflexedPosition(index)); return layout; }); } diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 18cabc309..96b6bea8c 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -106,7 +106,7 @@ export class DocumentLinksButton extends React.Component 3 || Math.abs(this._downY - touch.clientY) > 3)) { if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler)) { @@ -427,7 +427,7 @@ export class DocumentViewInternal extends DocComponent 3 || Math.abs(this._downY - e.clientY) > 3) { if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler) && (e.buttons === 1 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE))) { document.removeEventListener("pointermove", this.onPointerMove); @@ -594,7 +594,7 @@ export class DocumentViewInternal extends DocComponent this.props.removeDocument?.(this.props.Document); @undoBatch toggleDetail = () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`); - @undoBatch toggleLockPosition = () => this.Document.lockedPosition = this.Document.lockedPosition ? undefined : true; + @undoBatch toggleLockPosition = () => this.Document._lockedPosition = this.Document._lockedPosition ? undefined : true; @undoBatch @action drop = async (e: Event, de: DragManager.DropEvent) => { @@ -685,7 +685,7 @@ export class DocumentViewInternal extends DocComponent this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" }); diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index d76b61502..392565402 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -94,7 +94,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent { const alias = Doc.MakeAlias(Cast(this.layoutDoc[this.fieldKey], Doc, null)); alias.isLinkButton = undefined; - alias.layers = undefined; + alias._layerTags = undefined; alias.layoutKey = "layout"; this.props.addDocTab(alias, "add:right"); } diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index 6973079b0..4d8b6b55c 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -21,7 +21,6 @@ export const documentSchema = createSchema({ _currentTimecode: "number", // current play back time of a temporal document (video / audio) _timecodeToShow: "number", // the time that a document should be displayed (e.g., time an annotation should be displayed on a video) _timecodeToHIde: "number", // the time that a document should be hidden - isLabel: "boolean", // whether the document is a label or not (video / audio) markers: listSpec(Doc), // list of markers for audio / video x: "number", // x coordinate when in a freeform view y: "number", // y coordinate when in a freeform view @@ -96,7 +95,7 @@ export const documentSchema = createSchema({ isInPlaceContainer: "boolean",// whether the marked object will display addDocTab() calls that target "inPlace" destinations isLinkButton: "boolean", // whether document functions as a link follow button to follow the first link on the document when clicked layers: listSpec("string"), // which layers the document is part of - lockedPosition: "boolean", // whether the document can be moved (dragged) + _lockedPosition: "boolean", // whether the document can be moved (dragged) _lockedTransform: "boolean",// whether a freeformview can pan/zoom // drag drop properties diff --git a/src/fields/util.ts b/src/fields/util.ts index b9c5a13c1..b616515de 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -280,7 +280,6 @@ export function setter(target: any, in_prop: string | symbol | number, value: an let prop = in_prop; const effectiveAcl = getPropAcl(target, prop); if (effectiveAcl !== AclEdit && effectiveAcl !== AclAdmin) return true; - // if you're trying to change an acl but don't have Admin access / you're trying to change it to something that isn't an acceptable acl, you can't if (typeof prop === "string" && prop.startsWith("acl") && (effectiveAcl !== AclAdmin || ![...Object.values(SharingPermissions), undefined, "None"].includes(value))) return true; // if (typeof prop === "string" && prop.startsWith("acl") && !["Can Edit", "Can Augment", "Can View", "Not Shared", undefined].includes(value)) return true; diff --git a/src/server/database.ts b/src/server/database.ts index 41bf8b3da..8e0f99a1f 100644 --- a/src/server/database.ts +++ b/src/server/database.ts @@ -163,7 +163,7 @@ export namespace Database { } public async insert(value: any, collectionName = DocumentsCollection) { - if (this.db) { + if (this.db && value) { if ("id" in value) { value._id = value.id; delete value.id; @@ -185,7 +185,7 @@ export namespace Database { newProm = prom ? prom.then(run) : run(); this.currentWrites[id] = newProm; return newProm; - } else { + } else if (value) { this.onConnect.push(() => this.insert(value, collectionName)); } } diff --git a/src/server/websocket.ts b/src/server/websocket.ts index 7e3c4da82..4ae97913f 100644 --- a/src/server/websocket.ts +++ b/src/server/websocket.ts @@ -277,7 +277,11 @@ export namespace WebSocket { function addToListField(socket: Socket, diff: Diff, curListItems?: Transferable): void { diff.diff.$set = diff.diff.$addToSet; delete diff.diff.$addToSet;// convert add to set to a query of the current fields, and then a set of the composition of the new fields with the old ones const updatefield = Array.from(Object.keys(diff.diff.$set))[0]; - const newListItems = diff.diff.$set[updatefield].fields; + const newListItems = diff.diff.$set[updatefield]?.fields; + if (!newListItems) { + console.log("Error: addToListField - no new list items"); + return; + } const curList = (curListItems as any)?.fields?.[updatefield.replace("fields.", "")]?.fields.filter((item: any) => item !== undefined) || []; diff.diff.$set[updatefield].fields = [...curList, ...newListItems.filter((newItem: any) => newItem === null || !curList.some((curItem: any) => curItem.fieldId ? curItem.fieldId === newItem.fieldId : curItem.heading ? curItem.heading === newItem.heading : curItem === newItem))]; const sendBack = diff.diff.length !== diff.diff.$set[updatefield].fields.length; -- cgit v1.2.3-70-g09d2 From 17de222e15525ec5bda3c4e7113c1471dbfb906c Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 26 Feb 2021 17:33:51 -0500 Subject: fixes for getting documents into myFilesystem. fixes for setting layout fields without using an _ --- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 1 + src/fields/util.ts | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/client/views') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index ca5d4d371..438690067 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -786,7 +786,7 @@ export class CurrentUserUtils { treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, isFolder: true, treeViewType: "fileSystem", - _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true + _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "proto", system: true })); } return doc.myFilesystem as any as Doc; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index ff6c2860a..2a30e5fd0 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -359,6 +359,7 @@ export class MarqueeView extends React.Component { Doc.GetProto(doc).data = new List(selected); Doc.GetProto(doc).title = makeGroup ? "grouping" : "nested freeform"; + !this.props.isAnnotationOverlay && Doc.AddDocToList(Cast(Doc.UserDoc().myFileOrphans, Doc, null), "data", Doc.GetProto(doc)); doc._panX = doc._panY = 0; return doc; })(Doc.MakeCopy(Doc.UserDoc().emptyCollection as Doc, true)); diff --git a/src/fields/util.ts b/src/fields/util.ts index 26ab34ff4..7955fc9fb 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -284,7 +284,7 @@ export function setter(target: any, in_prop: string | symbol | number, value: an if (typeof prop === "string" && prop.startsWith("acl") && (effectiveAcl !== AclAdmin || ![...Object.values(SharingPermissions), undefined, "None"].includes(value))) return true; // if (typeof prop === "string" && prop.startsWith("acl") && !["Can Edit", "Can Augment", "Can View", "Not Shared", undefined].includes(value)) return true; - if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && (prop.startsWith("_") || layoutProps.includes(prop))) { + if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && prop.startsWith("_")) { // if (!prop.startsWith("_")) { // console.log(prop + " is deprecated - switch to _" + prop); // prop = "_" + prop; @@ -309,7 +309,7 @@ export function getter(target: any, in_prop: string | symbol | number, receiver: if (GetEffectiveAcl(target) === AclPrivate) return prop === HeightSym || prop === WidthSym ? returnZero : undefined; if (prop === LayoutSym) return target.__LAYOUT__; let search = false; - if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && (prop.startsWith("_") || layoutProps.includes(prop))) { + if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && prop.startsWith("_")) { // if (!prop.startsWith("_")) { // console.log(prop + " is deprecated - switch to _" + prop); // prop = "_" + prop; -- cgit v1.2.3-70-g09d2 From 3837b3746c771960e8a0f7b00648f739495ca92d Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 27 Feb 2021 12:43:07 -0500 Subject: more cleanup of unused fields and minor fixes to things like the color picker's display of the selcted documents background color. also a fix for textbox autoresizing when dragged small --- src/client/documents/Documents.ts | 33 +++++++--------- src/client/util/CurrentUserUtils.ts | 46 ++++++++++------------ src/client/views/InkingStroke.tsx | 2 +- src/client/views/MainView.tsx | 2 +- src/client/views/PreviewCursor.tsx | 2 +- src/client/views/StyleProvider.tsx | 6 +-- src/client/views/nodes/ColorBox.tsx | 5 +-- src/client/views/nodes/FilterBox.tsx | 2 +- src/client/views/nodes/FontIconBox.tsx | 1 - src/client/views/nodes/LabelBox.tsx | 8 +--- .../views/nodes/formattedText/FormattedTextBox.tsx | 17 +++----- 11 files changed, 51 insertions(+), 73 deletions(-) (limited to 'src/client/views') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 7a32596b0..d725e5fc9 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -93,6 +93,7 @@ export class DocumentOptions { dropAction?: DROPt = new DAInfo("what should happen to the source document when it's dropped onto this doc "); childDropAction?: DROPt = new DAInfo("what should happen to the source document when it's dropped onto a child of a collection "); targetDropAction?: DROPt = new DAInfo("what should happen to the source document when ??? "); + color?: string; // foreground color data doc backgroundColor?: STRt = new StrInfo("background color for data doc"); _backgroundColor?: STRt = new StrInfo("background color for each template layout doc (overrides backgroundColor)", true); _autoHeight?: BOOLt = new BoolInfo("whether document automatically resizes vertically to display contents", true); @@ -109,9 +110,6 @@ export class DocumentOptions { _dimUnit?: DIMt = new DimInfo("units of collectionMulti{row,col} element's width or height - 'px' or '*' for pixels or relative units", true); _fitWidth?: BOOLt = new BoolInfo("whether document should scale its contents to fit its rendered width or not (e.g., for PDFviews)", true); _fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents - color?: string; // foreground color data doc - _color?: string; // foreground color for each template layout doc (overrides color) - _clipWidth?: number; // percent transition from before to after in comparisonBox _lockedPosition?: boolean; // lock the x,y coordinates of the document so that it can't be dragged _lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed _freeformLOD?: boolean; // whether to use LOD to render a freeform document @@ -122,6 +120,7 @@ export class DocumentOptions { _chromeStatus?: string; _layerTags?: List; // layer tags a document has (used for tab filtering "layers" in document tab) _searchDoc?: boolean; // is this a search document (used to change UI for search results in schema view) + _forceActive?: boolean; // flag to handle pointer events when not selected (or otherwise active) _stayInCollection?: boolean;// whether the document should remain in its collection when someone tries to drag and drop it elsewhere _raiseWhenDragged?: boolean; // whether a document is brought to front when dragged. _hideContextMenu?: boolean; // whether the context menu can be shown @@ -141,7 +140,8 @@ export class DocumentOptions { _fontSize?: string; _fontWeight?: number; _fontFamily?: string; - _curPage?: number; + _pivotField?: string; // field key used to determine headings for sections in stacking, masonry, pivot views + _curPage?: number; // current page of a PDF or other? paginated document _currentTimecode?: number; // the current timecode of a time-based document (e.g., current time of a video) value is in seconds _currentFrame?: number; // the current frame of a frame-based collection (e.g., progressive slide) _timecodeToShow?: number; // the time that a document should be displayed (e.g., when an annotation shows up as a video plays) @@ -162,7 +162,6 @@ export class DocumentOptions { toolTip?: string; // tooltip to display on hover dontUndo?: boolean; // whether button clicks should be undoable (this is set to true for Undo/Redo/and sidebar buttons that open the siebar panel) description?: string; // added for links - forceActive?: boolean; layout?: string | Doc; // default layout string for a document contentPointerEvents?: string; // pointer events allowed for content of a document view. eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents childLimitHeight?: number; // whether to limit the height of colleciton children. 0 - means height can be no bigger than width @@ -177,7 +176,6 @@ export class DocumentOptions { templates?: List; hero?: ImageField; // primary image that best represents a compound document (e.g., for a buxton device document that has multiple images) caption?: RichTextField; - ignoreClick?: boolean; isAnnotating?: boolean; // whether we web document is annotation mode where links can't be clicked to allow annotations to be created opacity?: number; defaultBackgroundColor?: string; @@ -200,18 +198,16 @@ export class DocumentOptions { "onClick-rawScript"?: string; // onClick script in raw text form "onCheckedClick-rawScript"?: string; // onChecked script in raw text form "onCheckedClick-params"?: List; // parameter list for onChecked treeview functions - _pivotField?: string; // field key used to determine headings for sections in stacking, masonry, pivot views - _columnHeaders?: List; // headers for stacking views - _schemaHeaders?: List; // headers for schema view + columnHeaders?: List; // headers for stacking views + schemaHeaders?: List; // headers for schema view + clipWidth?: number; // percent transition from before to after in comparisonBox dockingConfig?: string; annotationOn?: Doc; isPushpin?: boolean; removeDropProperties?: List; // list of properties that should be removed from a document when it is dropped. e.g., a creator button may be forceActive to allow it be dragged, but the forceActive property can be removed from the dropped document - dbDoc?: Doc; iconShape?: string; // shapes of the fonticon border linkRelationship?: string; // type of relatinoship a link represents - ischecked?: ScriptField; // returns whether a font icon box is checked - activeInkPen?: Doc; // which pen document is currently active (used as the radio button state for the 'unhecked' pen tool scripts) + ignoreClick?: boolean; onClick?: ScriptField; onDoubleClick?: ScriptField; onChildClick?: ScriptField; // script given to children of a collection to execute when they are clicked @@ -222,7 +218,7 @@ export class DocumentOptions { dragFactory?: Doc; // document to create when dragging with a suitable onDragStart script clickFactory?: Doc; // document to create when clicking on a button with a suitable onClick script onDragStart?: ScriptField; //script to execute at start of drag operation -- e.g., when a "creator" button is dragged this script generates a different document to drop - clipboard?: Doc; + cloneFieldFilter?: List; // fields not to copy when the document is clonedclipboard?: Doc; useCors?: boolean; icon?: string; target?: Doc; // available for use in scripts as the primary target document @@ -230,7 +226,6 @@ export class DocumentOptions { targetContainer?: Doc; // document whose proto will be set to 'panel' as the result of a onClick click script searchFileTypes?: List; // file types allowed in a search query strokeWidth?: number; - cloneFieldFilter?: List; // fields not to copy when the document is cloned freezeChildren?: string; // whether children are now allowed to be added and or removed from a collection treeViewPreventOpen?: boolean; // ignores the treeViewOpen Doc flag which allows a treeViewItem's expand/collapse state to be independent of other views of the same document in the tree view treeViewHideTitle?: boolean; // whether to hide the top document title of a tree view @@ -245,17 +240,17 @@ export class DocumentOptions { treeViewDefaultExpandedView?: string; // default expanded view sidebarColor?: string; // background color of text sidebar sidebarViewType?: string; // collection type of text sidebar - limitHeight?: number; // maximum height for newly created (eg, from pasting) text documents + docMaxHeight?: number; // maximum height for newly created (eg, from pasting) text documents textTransform?: string; // is linear view expanded letterSpacing?: string; // is linear view expanded flexDirection?: "unset" | "row" | "column" | "row-reverse" | "column-reverse"; selectedIndex?: number; // which item in a linear view has been selected using the "thumb doc" ui - syntaxColor?: string; // can be applied to text for syntax highlighting all matches in the text + clipboard?: Doc; searchQuery?: string; // for quersyBox linearViewIsExpanded?: boolean; // is linear view expanded useLinkSmallAnchor?: boolean; // whether links to this document should use a miniature linkAnchorBox border?: string; //for searchbox - _hovercolor?: string; + hoverBackgroundColor?: string; // background color of a label when hovered } export namespace Docs { @@ -724,7 +719,7 @@ export namespace Docs { } export function ComparisonDocument(options: DocumentOptions = { title: "Comparison Box" }) { - return InstanceFromProto(Prototypes.get(DocumentType.COMPARISON), "", { _clipWidth: 50, _backgroundColor: "gray", targetDropAction: "alias", ...options }); + return InstanceFromProto(Prototypes.get(DocumentType.COMPARISON), "", { clipWidth: 50, _backgroundColor: "gray", targetDropAction: "alias", ...options }); } export function AudioDocument(url: string, options: DocumentOptions = {}) { @@ -868,7 +863,7 @@ export namespace Docs { } export function SchemaDocument(schemaHeaders: SchemaHeaderField[], documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _schemaHeaders: schemaHeaders.length ? new List(schemaHeaders) : undefined, ...options, _viewType: CollectionViewType.Schema }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaHeaders: schemaHeaders.length ? new List(schemaHeaders) : undefined, ...options, _viewType: CollectionViewType.Schema }); } export function TreeDocument(documents: Array, options: DocumentOptions, id?: string) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 438690067..eab372d5d 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -361,7 +361,7 @@ export class CurrentUserUtils { static creatorBtnDescriptors(doc: Doc): { title: string, toolTip: string, icon: string, drag?: string, ignoreClick?: boolean, - click?: string, ischecked?: string, activeInkPen?: Doc, backgroundColor?: string, dragFactory?: Doc, noviceMode?: boolean, clickFactory?: Doc + click?: string, backgroundColor?: string, dragFactory?: Doc, noviceMode?: boolean, clickFactory?: Doc }[] { if (doc.emptyPresentation === undefined) { doc.emptyPresentation = Docs.Create.PresDocument(new List(), @@ -481,7 +481,7 @@ export class CurrentUserUtils { } } const buttons = CurrentUserUtils.creatorBtnDescriptors(doc).filter(d => !alreadyCreatedButtons?.includes(d.title)); - const creatorBtns = buttons.map(({ title, toolTip, icon, ignoreClick, drag, click, ischecked, activeInkPen, backgroundColor, dragFactory, noviceMode, clickFactory }) => Docs.Create.FontIconDocument({ + const creatorBtns = buttons.map(({ title, toolTip, icon, ignoreClick, drag, click, backgroundColor, dragFactory, noviceMode, clickFactory }) => Docs.Create.FontIconDocument({ _nativeWidth: 50, _nativeHeight: 50, _width: 35, _height: 35, icon, title, @@ -490,8 +490,6 @@ export class CurrentUserUtils { dropAction: "alias", onDragStart: drag ? ScriptField.MakeFunction(drag) : undefined, onClick: click ? ScriptField.MakeScript(click) : undefined, - ischecked: ischecked ? ComputedField.MakeFunction(ischecked) : undefined, - activeInkPen, backgroundColor, _hideContextMenu: true, removeDropProperties: new List(["_stayInCollection"]), @@ -609,7 +607,7 @@ export class CurrentUserUtils { // SEts up mobile buttons for inside mobile menu static setupMobileButtons(doc?: Doc, buttons?: string[]) { - const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [ + const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, activePen?: Doc, backgroundColor?: string, info: string, dragFactory?: Doc }[] = [ { title: "DASHBOARDS", icon: "bars", click: 'switchToMobileLibrary()', backgroundColor: "lightgrey", info: "Access your Dashboards from your mobile, and navigate through all of your documents. " }, { title: "UPLOAD", icon: "upload", click: 'openMobileUploads()', backgroundColor: "lightgrey", info: "Upload files from your mobile device so they can be accessed on Dash Web." }, { title: "MOBILE UPLOAD", icon: "mobile", click: 'switchToMobileUploadCollection()', backgroundColor: "lightgrey", info: "Access the collection of your mobile uploads." }, @@ -657,12 +655,12 @@ export class CurrentUserUtils { static setupThumbButtons(doc: Doc) { - const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, pointerDown?: string, pointerUp?: string, ischecked?: string, clipboard?: Doc, activeInkPen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [ - { title: "use pen", icon: "pen-nib", pointerUp: "resetPen()", pointerDown: 'setPen(2, this.backgroundColor)', backgroundColor: "blue", ischecked: `sameDocs(this.activeInkPen, this)`, activeInkPen: doc }, - { title: "use highlighter", icon: "highlighter", pointerUp: "resetPen()", pointerDown: 'setPen(20, this.backgroundColor)', backgroundColor: "yellow", ischecked: `sameDocs(this.activeInkPen, this)`, activeInkPen: doc }, - { title: "notepad", icon: "clipboard", pointerUp: "GestureOverlay.Instance.closeFloatingDoc()", pointerDown: 'GestureOverlay.Instance.openFloatingDoc(this.clipboard)', clipboard: Docs.Create.FreeformDocument([], { _width: 300, _height: 300, system: true }), backgroundColor: "orange", ischecked: `sameDocs(this.activeInkPen, this)`, activeInkPen: doc }, - { title: "interpret text", icon: "font", pointerUp: "setToolglass('none')", pointerDown: "setToolglass('inktotext')", backgroundColor: "orange", ischecked: `sameDocs(this.activeInkPen, this)`, activeInkPen: doc }, - { title: "ignore gestures", icon: "signature", pointerUp: "setToolglass('none')", pointerDown: "setToolglass('ignoregesture')", backgroundColor: "green", ischecked: `sameDocs(this.activeInkPen, this)`, activeInkPen: doc }, + const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, pointerDown?: string, pointerUp?: string, clipboard?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [ + { title: "use pen", icon: "pen-nib", pointerUp: "resetPen()", pointerDown: 'setPen(2, this.backgroundColor)', backgroundColor: "blue" }, + { title: "use highlighter", icon: "highlighter", pointerUp: "resetPen()", pointerDown: 'setPen(20, this.backgroundColor)', backgroundColor: "yellow" }, + { title: "notepad", icon: "clipboard", pointerUp: "GestureOverlay.Instance.closeFloatingDoc()", pointerDown: 'GestureOverlay.Instance.openFloatingDoc(this.clipboard)', clipboard: Docs.Create.FreeformDocument([], { _width: 300, _height: 300, system: true }), backgroundColor: "orange" }, + { title: "interpret text", icon: "font", pointerUp: "setToolglass('none')", pointerDown: "setToolglass('inktotext')", backgroundColor: "orange" }, + { title: "ignore gestures", icon: "signature", pointerUp: "setToolglass('none')", pointerDown: "setToolglass('ignoregesture')", backgroundColor: "green" }, ]; return docProtoData.map(data => Docs.Create.FontIconDocument({ _nativeWidth: 10, _nativeHeight: 10, _width: 10, _height: 10, title: data.title, icon: data.icon, @@ -670,7 +668,6 @@ export class CurrentUserUtils { onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined, clipboard: data.clipboard, onPointerUp: data.pointerUp ? ScriptField.MakeScript(data.pointerUp) : undefined, onPointerDown: data.pointerDown ? ScriptField.MakeScript(data.pointerDown) : undefined, - ischecked: data.ischecked ? ComputedField.MakeFunction(data.ischecked) : undefined, activeInkPen: data.activeInkPen, backgroundColor: data.backgroundColor, removeDropProperties: new List(["dropAction"]), dragFactory: data.dragFactory, system: true })); } @@ -728,14 +725,14 @@ export class CurrentUserUtils { // setup a color picker if (doc.myColorPicker === undefined) { const color = Docs.Create.ColorDocument({ - title: "color picker", _width: 300, dropAction: "alias", _hideContextMenu: true, _stayInCollection: true, forceActive: true, removeDropProperties: new List(["dropAction", "_stayInCollection", "_hideContextMenu", "forceActive"]), system: true + title: "color picker", _width: 300, dropAction: "alias", _hideContextMenu: true, _stayInCollection: true, _forceActive: true, removeDropProperties: new List(["dropAction", "_stayInCollection", "_hideContextMenu", "forceActive"]), system: true }); doc.myColorPicker = new PrefetchProxy(color); } if (doc.myTools === undefined) { const toolsStack = new PrefetchProxy(Docs.Create.StackingDocument([doc.myCreators as Doc, doc.myColorPicker as Doc], { - title: "My Tools", _width: 500, _yMargin: 20, ignoreClick: true, _lockedPosition: true, _chromeStatus: "disabled", forceActive: true, system: true, _stayInCollection: true, _hideContextMenu: true, + title: "My Tools", _width: 500, _yMargin: 20, ignoreClick: true, _lockedPosition: true, _chromeStatus: "disabled", _forceActive: true, system: true, _stayInCollection: true, _hideContextMenu: true, })) as any as Doc; doc.myTools = toolsStack; @@ -748,7 +745,7 @@ export class CurrentUserUtils { if (doc.myDashboards === undefined) { doc.myDashboards = new PrefetchProxy(Docs.Create.TreeDocument([], { title: "My Dashboards", _height: 400, - treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias", + treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })); @@ -764,7 +761,7 @@ export class CurrentUserUtils { if (doc.myPresentations === undefined) { doc.myPresentations = new PrefetchProxy(Docs.Create.TreeDocument([], { title: "My Presentations", _height: 100, - treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias", + treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })); @@ -783,7 +780,7 @@ export class CurrentUserUtils { doc.myFileRoot = Docs.Create.TreeDocument([], { title: "file root", _stayInCollection: true, system: true, isFolder: true }); doc.myFilesystem = new PrefetchProxy(Docs.Create.TreeDocument([doc.myFileRoot as Doc, doc.myFileOrphans as Doc], { title: "My Documents", _height: 100, - treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias", + treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, isFolder: true, treeViewType: "fileSystem", _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "proto", system: true @@ -797,7 +794,7 @@ export class CurrentUserUtils { if (doc.myRecentlyClosedDocs === undefined) { doc.myRecentlyClosedDocs = new PrefetchProxy(Docs.Create.TreeDocument([], { title: "Recently Closed", _height: 500, - treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias", + treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })); @@ -812,7 +809,7 @@ export class CurrentUserUtils { if (doc.myFilter === undefined) { doc.myFilter = new PrefetchProxy(Docs.Create.FilterDocument({ title: "FilterDoc", _height: 500, - treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "none", + treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "none", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })); @@ -828,7 +825,7 @@ export class CurrentUserUtils { doc.treeViewOpen = true; doc.treeViewExpandedView = "fields"; doc.myUserDoc = new PrefetchProxy(Docs.Create.TreeDocument([doc], { - treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, title: "My UserDoc", + treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, title: "My UserDoc", treeViewTruncateTitleWidth: 150, treeViewPreventOpen: false, ignoreClick: true, _lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same", system: true })) as any as Doc; @@ -858,7 +855,7 @@ export class CurrentUserUtils { } static blist = (opts: DocumentOptions, docs: Doc[]) => new PrefetchProxy(Docs.Create.LinearDocument(docs, { - ...opts, _gridGap: 5, _xMargin: 5, _yMargin: 5, _height: 42, _width: 100, boxShadow: "0 0", forceActive: true, + ...opts, _gridGap: 5, _xMargin: 5, _yMargin: 5, _height: 42, _width: 100, boxShadow: "0 0", _forceActive: true, dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), backgroundColor: "black", treeViewPreventOpen: true, _lockedPosition: true, _chromeStatus: "disabled", linearViewIsExpanded: true, system: true })) as any as Doc @@ -929,7 +926,7 @@ export class CurrentUserUtils { static setupImportSidebar(doc: Doc) { if (doc.myImportDocs === undefined) { doc.myImportDocs = new PrefetchProxy(Docs.Create.StackingDocument([], { - title: "My ImportDocuments", forceActive: true, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0, + title: "My ImportDocuments", _forceActive: true, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0, childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, _lockedPosition: true, _chromeStatus: "disabled", system: true })); } @@ -1001,7 +998,6 @@ export class CurrentUserUtils { doc.noviceMode = doc.noviceMode === undefined ? "true" : doc.noviceMode; doc.title = Doc.CurrentUserEmail; doc._raiseWhenDragged = true; - doc.activeInkPen = doc; doc.activeInkColor = StrCast(doc.activeInkColor, "rgb(0, 0, 0)"); doc.activeInkWidth = StrCast(doc.activeInkWidth, "1"); doc.activeInkBezier = StrCast(doc.activeInkBezier, "0"); @@ -1200,9 +1196,9 @@ export class CurrentUserUtils { CurrentUserUtils.openDashboard(userDoc, dashboardDoc); } - public static GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number, noMargins?: boolean, annotationOn?: Doc) { + public static GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number, noMargins?: boolean, annotationOn?: Doc, maxHeight?: number) { const tbox = Docs.Create.TextDocument("", { - _xMargin: noMargins ? 0 : undefined, _yMargin: noMargins ? 0 : undefined, annotationOn, + _xMargin: noMargins ? 0 : undefined, _yMargin: noMargins ? 0 : undefined, annotationOn, docMaxHeight: maxHeight, _width: width || 200, _height: height || 100, x: x, y: y, _autoHeight: true, _fontSize: StrCast(Doc.UserDoc().fontSize), _fontFamily: StrCast(Doc.UserDoc().fontFamily), title }); diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 19b23af13..462d78865 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -233,7 +233,7 @@ export function SetActiveFillColor(value: string) { ActiveInkPen() && (ActiveInk export function SetActiveArrowStart(value: string) { ActiveInkPen() && (ActiveInkPen().activeArrowStart = value); } export function SetActiveArrowEnd(value: string) { ActiveInkPen() && (ActiveInkPen().activeArrowEnd = value); } export function SetActiveDash(dash: string): void { !isNaN(parseInt(dash)) && ActiveInkPen() && (ActiveInkPen().activeDash = dash); } -export function ActiveInkPen(): Doc { return Cast(Doc.UserDoc().activeInkPen, Doc, null); } +export function ActiveInkPen(): Doc { return Doc.UserDoc(); } export function ActiveInkColor(): string { return StrCast(ActiveInkPen()?.activeInkColor, "black"); } export function ActiveFillColor(): string { return StrCast(ActiveInkPen()?.activeFillColor, ""); } export function ActiveArrowStart(): string { return StrCast(ActiveInkPen()?.activeArrowStart, ""); } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index d17668ea7..01afed5f9 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -228,7 +228,7 @@ export class MainView extends React.Component { createNewPresentation = async () => { if (!await this.userDoc.myPresentations) { this.userDoc.myPresentations = new PrefetchProxy(Docs.Create.TreeDocument([], { - title: "PRESENTATION TRAILS", _height: 100, forceActive: true, boxShadow: "0 0", _lockedPosition: true, treeViewOpen: true, system: true + title: "PRESENTATION TRAILS", _height: 100, _forceActive: true, boxShadow: "0 0", _lockedPosition: true, treeViewOpen: true, system: true })); } const pres = Docs.Create.PresDocument(new List(), diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 5b57ad19f..679a4b81e 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -79,7 +79,7 @@ export class PreviewCursor extends React.Component<{}> { else { // creates text document FormattedTextBox.PasteOnLoad = e; - UndoManager.RunInBatch(() => PreviewCursor._addLiveTextDoc(CurrentUserUtils.GetNewTextDoc("-pasted text-", newPoint[0], newPoint[1], 500)), "paste"); + UndoManager.RunInBatch(() => PreviewCursor._addLiveTextDoc(CurrentUserUtils.GetNewTextDoc("-pasted text-", newPoint[0], newPoint[1], 500, undefined, undefined, undefined, 750)), "paste"); } } else //pasting in images diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 69a1e4db2..e5b2a332a 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -84,15 +84,15 @@ export function DefaultStyleProvider(doc: Opt, props: Opt 400 || col.alpha() < 0.25) return "black"; return "white"; - case StyleProp.Hidden: return BoolCast(doc?._hidden, BoolCast(doc?.hidden)); - case StyleProp.BorderRounding: return StrCast(doc?._borderRounding, StrCast(doc?.borderRounding)); + case StyleProp.Hidden: return BoolCast(doc?._hidden); + case StyleProp.BorderRounding: return StrCast(doc?._borderRounding); case StyleProp.TitleHeight: return 15; case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry].includes(doc?._viewType as any) || doc?.type === DocumentType.RTF) && doc?._showTitle && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0; case StyleProp.BackgroundColor: { if (isAnchor && docProps) return "transparent"; if (isCaption) return "rgba(0,0,0 ,0.4)"; if (Doc.UserDoc().renderStyle === "comic") return "transparent"; - let docColor: Opt = StrCast(doc?._backgroundColor, StrCast(doc?.backgroundColor)); + let docColor: Opt = StrCast(doc?._backgroundColor); if (!docProps) { if (MainView.Instance.LastButton === doc) return darkScheme() ? "dimgrey" : "lightgrey"; switch (doc?.type) { diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx index d5b6a269e..715ec92f8 100644 --- a/src/client/views/nodes/ColorBox.tsx +++ b/src/client/views/nodes/ColorBox.tsx @@ -11,7 +11,7 @@ import { StrCast } from "../../../fields/Types"; import { SelectionManager } from "../../util/SelectionManager"; import { undoBatch } from "../../util/UndoManager"; import { ViewBoxBaseComponent } from "../DocComponent"; -import { ActiveInkPen, ActiveInkWidth, ActiveInkBezierApprox, SetActiveInkColor, SetActiveInkWidth, SetActiveBezierApprox } from "../InkingStroke"; +import { ActiveInkPen, ActiveInkWidth, ActiveInkBezierApprox, SetActiveInkColor, SetActiveInkWidth, SetActiveBezierApprox, ActiveInkColor } from "../InkingStroke"; import "./ColorBox.scss"; import { FieldView, FieldViewProps } from './FieldView'; import { DocumentType } from "../../documents/DocumentTypes"; @@ -60,8 +60,7 @@ export class ColorBox extends ViewBoxBaseComponent + color={StrCast(selDoc?._backgroundColor, ActiveInkColor())} />
{ActiveInkWidth() ?? 2}
diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx index 1ab3ede6e..f42f487cf 100644 --- a/src/client/views/nodes/FilterBox.tsx +++ b/src/client/views/nodes/FilterBox.tsx @@ -122,7 +122,7 @@ export class FilterBox extends ViewBoxBaseComponent; if (facetHeader === "text" || facetValues.rtFields / allCollectionDocs.length > 0.1) { - newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, system: true, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, forceActive: true, ignoreClick: true }); + newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, system: true, _stayInCollection: true, _hideContextMenu: true, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, _forceActive: true, ignoreClick: true }); Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox newFacet._textBoxPadding = 4; const scriptText = `setDocFilter(this?.target, "${facetHeader}", text, "match")`; diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx index 121b9f26c..56c79cde9 100644 --- a/src/client/views/nodes/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox.tsx @@ -50,7 +50,6 @@ export class FontIconBox extends DocComponent( style={{ width: presSize, height: presSize, filter: `invert(${color === "white" ? "100%" : "0%"})`, marginBottom: "5px" }} />; const button =
{this.props.noSidebar || !this.layoutDoc._showSidebar || this.sidebarWidthPercent === "0%" ? (null) : this.sidebarCollection} - {this.sidebarHandle} + {this.Document._singleLine ? (null) : this.sidebarHandle} {!this.layoutDoc._showAudio ? (null) : this.audioHandle}
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts index a1a404e10..eae4c0179 100644 --- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts +++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts @@ -144,6 +144,10 @@ export function buildKeymap>(schema: S, props: any, mapKey bind("Alt-\\", setBlockType(schema.nodes.paragraph)); bind("Shift-Ctrl-\\", setBlockType(schema.nodes.code_block)); + bind("Ctrl-m", (state: EditorState, dispatch: (tx: Transaction) => void) => { + dispatch(state.tr.replaceSelectionWith(schema.nodes.dashField.create({ fieldKey: "math" + Utils.GenerateGuid() }))); + }) + for (let i = 1; i <= 6; i++) { bind("Shift-Ctrl-" + i, setBlockType(schema.nodes.heading, { level: i })); } diff --git a/webpack.config.js b/webpack.config.js index c973be1ed..30967d618 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -74,6 +74,10 @@ module.exports = { } }] }, + { + test: /\.(woff|woff2|ttf|eot|otf|svg)$/, + use: 'file-loader?name=fonts/[name].[ext]!static' + }, { test: /\.scss|css$/, use: [{ @@ -84,7 +88,7 @@ module.exports = { }, { loader: "sass-loader" - } + }, ] }, { -- cgit v1.2.3-70-g09d2 From faf9dc5ca6a7380f3b040dc2ddbe07c29689e014 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 2 Mar 2021 12:39:58 -0500 Subject: some cleanup and extensions to Equationbox stuff. can sort of be nested in text docs with ctrl-m. --- src/client/views/nodes/EquationBox.tsx | 31 ++++++--- .../views/nodes/formattedText/DashFieldView.tsx | 12 ++-- .../views/nodes/formattedText/EquationView.tsx | 75 ++++++++++++++++++++++ .../views/nodes/formattedText/FormattedTextBox.tsx | 12 ++-- .../formattedText/ProsemirrorExampleTransfer.ts | 2 +- src/client/views/nodes/formattedText/nodes_rts.ts | 13 ++++ 6 files changed, 124 insertions(+), 21 deletions(-) create mode 100644 src/client/views/nodes/formattedText/EquationView.tsx (limited to 'src/client/views') diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx index 8ded4111c..7f9fc342a 100644 --- a/src/client/views/nodes/EquationBox.tsx +++ b/src/client/views/nodes/EquationBox.tsx @@ -12,6 +12,7 @@ import { simulateMouseClick } from '../../../Utils'; import { TraceMobx } from '../../../fields/util'; import { reaction, action } from 'mobx'; import { Docs } from '../../documents/Documents'; +import { LightboxView } from '../LightboxView'; const EquationSchema = createSchema({}); @@ -24,7 +25,7 @@ export class EquationBox extends ViewBoxBaseComponent = React.createRef(); componentDidMount() { - if (EquationBox.SelectOnLoad === this.rootDoc[Id]) { + if (EquationBox.SelectOnLoad === this.rootDoc[Id] && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath()))) { this.props.select(false); this._ref.current!.mathField.focus(); @@ -40,24 +41,36 @@ export class EquationBox extends ViewBoxBaseComponent { - if (e.key === "Enter") { - const _height = Number(getComputedStyle(this._ref.current!.element.current).height.replace("px", "")); - const _width = Number(getComputedStyle(this._ref.current!.element.current).width.replace("px", "")); - this.layoutDoc._width = _width; - this.layoutDoc._height = _height; - const nextEq = Docs.Create.EquationDocument({ title: "# math", text: StrCast(this.dataDoc.text), x: NumCast(this.layoutDoc.x), y: NumCast(this.layoutDoc.y) + _height + 10, _width, _height: 35 }); + const _height = Number(getComputedStyle(this._ref.current!.element.current).height.replace("px", "")); + const _width = Number(getComputedStyle(this._ref.current!.element.current).width.replace("px", "")); + if (e.key === "Enter" || e.key === "Tab") { + const nextEq = Docs.Create.EquationDocument({ + title: "# math", text: StrCast(this.dataDoc.text), _width, _height: 25, + x: NumCast(this.layoutDoc.x) + (e.key === "Tab" ? _width + 10 : 0), y: NumCast(this.layoutDoc.y) + (e.key === "Enter" ? _height + 10 : 0) + }); EquationBox.SelectOnLoad = nextEq[Id]; this.props.addDocument?.(nextEq); e.stopPropagation(); } if (e.key === "Backspace" && !this.dataDoc.text) this.props.removeDocument?.(this.rootDoc); } - onChange = (str: string) => this.dataDoc.text = str; + onChange = (str: string) => { + this.dataDoc.text = str; + const _height = Number(getComputedStyle(this._ref.current!.element.current).height.replace("px", "")); + const _width = Number(getComputedStyle(this._ref.current!.element.current).width.replace("px", "")); + this.layoutDoc._width = Math.max(35, _width); + this.layoutDoc._height = Math.max(25, _height); + } render() { TraceMobx(); - return (
this.props.isSelected() && !e.ctrlKey && e.stopPropagation()}> + return (
!e.ctrlKey && e.stopPropagation()} + style={{ + pointerEvents: !this.props.isSelected() ? "none" : undefined, + }} + >
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index b39a845db..62f65cdae 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -1,18 +1,18 @@ -import { IReactionDisposer, observable, computed, action } from "mobx"; -import { Doc, DocListCast, Field, DataSym } from "../../../../fields/Doc"; +import { action, computed, IReactionDisposer, observable } from "mobx"; +import { observer } from "mobx-react"; +import * as ReactDOM from 'react-dom'; +import { DataSym, Doc, DocListCast, Field } from "../../../../fields/Doc"; import { List } from "../../../../fields/List"; import { listSpec } from "../../../../fields/Schema"; import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField"; import { ComputedField } from "../../../../fields/ScriptField"; import { Cast, StrCast } from "../../../../fields/Types"; import { DocServer } from "../../../DocServer"; +import { DocUtils } from "../../../documents/Documents"; import { CollectionViewType } from "../../collections/CollectionView"; +import "./DashFieldView.scss"; import { FormattedTextBox } from "./FormattedTextBox"; import React = require("react"); -import * as ReactDOM from 'react-dom'; -import "./DashFieldView.scss"; -import { observer } from "mobx-react"; -import { DocUtils } from "../../../documents/Documents"; export class DashFieldView { _fieldWrapper: HTMLDivElement; // container for label and value diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx new file mode 100644 index 000000000..eff018635 --- /dev/null +++ b/src/client/views/nodes/formattedText/EquationView.tsx @@ -0,0 +1,75 @@ +import EquationEditor from "equation-editor-react"; +import { IReactionDisposer } from "mobx"; +import { observer } from "mobx-react"; +import * as ReactDOM from 'react-dom'; +import { Doc } from "../../../../fields/Doc"; +import { StrCast } from "../../../../fields/Types"; +import "./DashFieldView.scss"; +import { FormattedTextBox } from "./FormattedTextBox"; +import React = require("react"); + +export class EquationView { + _fieldWrapper: HTMLDivElement; // container for label and value + + constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) { + this._fieldWrapper = document.createElement("div"); + this._fieldWrapper.style.width = node.attrs.width; + this._fieldWrapper.style.height = node.attrs.height; + this._fieldWrapper.style.fontWeight = "bold"; + this._fieldWrapper.style.position = "relative"; + this._fieldWrapper.style.display = "inline-block"; + this._fieldWrapper.onkeypress = function (e: any) { e.stopPropagation(); }; + this._fieldWrapper.onkeydown = function (e: any) { e.stopPropagation(); }; + this._fieldWrapper.onkeyup = function (e: any) { e.stopPropagation(); }; + this._fieldWrapper.onmousedown = function (e: any) { e.stopPropagation(); }; + + ReactDOM.render(, this._fieldWrapper); + (this as any).dom = this._fieldWrapper; + } + destroy() { ReactDOM.unmountComponentAtNode(this._fieldWrapper); } + selectNode() { } +} + +interface IEquationViewInternal { + fieldKey: string; + tbox: FormattedTextBox; + width: number; + height: number; +} + +@observer +export class EquationViewInternal extends React.Component { + _reactionDisposer: IReactionDisposer | undefined; + _textBoxDoc: Doc; + _fieldKey: string; + + constructor(props: IEquationViewInternal) { + super(props); + this._fieldKey = this.props.fieldKey; + this._textBoxDoc = this.props.tbox.props.Document; + } + + componentWillUnmount() { this._reactionDisposer?.(); } + + render() { + return
+ +
; + } +} \ No newline at end of file diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 5066578aa..104d60fff 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -40,6 +40,7 @@ import { DashDocView } from "./RichTextSchema"; import { DashDocCommentView } from "./DashDocCommentView"; import { DashFieldView } from "./DashFieldView"; +import { EquationView } from "./EquationView"; import { SummaryView } from "./SummaryView"; import { OrderedListView } from "./OrderedListView"; import { FootnoteView } from "./FootnoteView"; @@ -596,7 +597,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const options = cm.findByDescription("Options..."); const optionItems = options && "subitems" in options ? options.subitems : []; - !Doc.UserDoc().noviceMode && optionItems.push({ description: !this.Document._singleLine ? "Make Single Line" : "Make Multi Line", event: () => this.layoutDoc._singleLine = !this.layoutDoc._singleLine, icon: "expand-arrows-alt" }); + optionItems.push({ description: !this.Document._noSidebar ? "Hide Sidebar Handle" : "Show Sidebar Handle", event: () => this.layoutDoc._noSidebar = !this.layoutDoc._noSidebar, icon: "expand-arrows-alt" }); + optionItems.push({ description: !this.Document._singleLine ? "Make Single Line" : "Make Multi Line", event: () => this.layoutDoc._singleLine = !this.layoutDoc._singleLine, icon: "expand-arrows-alt" }); optionItems.push({ description: `${this.Document._autoHeight ? "Lock" : "Auto"} Height`, event: () => this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight, icon: "plus" }); !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "eye" }); this._downX = this._downY = Number.NaN; @@ -745,7 +747,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp // Since we also monitor all component height changes, this will update the document's height. resetNativeHeight = (scrollHeight: number) => { const nh = this.layoutDoc.isTemplateForField ? 0 : NumCast(this.layoutDoc._nativeHeight); - this.rootDoc[this.fieldKey + "-height"] = scrollHeight * (this.props.scaling?.() || 1) + this.titleHeight; + this.rootDoc[this.fieldKey + "-height"] = scrollHeight + this.titleHeight; if (nh) this.layoutDoc._nativeHeight = scrollHeight; } @@ -1060,6 +1062,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp dashComment(node, view, getPos) { return new DashDocCommentView(node, view, getPos); }, dashDoc(node, view, getPos) { return new DashDocView(node, view, getPos, self); }, dashField(node, view, getPos) { return new DashFieldView(node, view, getPos, self); }, + equation(node, view, getPos) { return new EquationView(node, view, getPos, self); }, summary(node, view, getPos) { return new SummaryView(node, view, getPos); }, ordered_list(node, view, getPos) { return new OrderedListView(); }, footnote(node, view, getPos) { return new FootnoteView(node, view, getPos); } @@ -1163,7 +1166,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } onPointerUp = (e: React.PointerEvent): void => { - FormattedTextBox.CanAnnotate = true; if (!this._editorView?.state.selection.empty && FormattedTextBox.CanAnnotate) this.setupAnchorMenu(); if (!this._downEvent) return; this._downEvent = false; @@ -1540,8 +1542,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp }} />
- {this.props.noSidebar || !this.layoutDoc._showSidebar || this.sidebarWidthPercent === "0%" ? (null) : this.sidebarCollection} - {this.Document._singleLine ? (null) : this.sidebarHandle} + {(this.props.noSidebar || this.Document._noSidebar) || !this.layoutDoc._showSidebar || this.sidebarWidthPercent === "0%" ? (null) : this.sidebarCollection} + {(this.props.noSidebar || this.Document._noSidebar) || this.Document._singleLine ? (null) : this.sidebarHandle} {!this.layoutDoc._showAudio ? (null) : this.audioHandle}
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts index eae4c0179..aa51a3a64 100644 --- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts +++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts @@ -145,7 +145,7 @@ export function buildKeymap>(schema: S, props: any, mapKey bind("Shift-Ctrl-\\", setBlockType(schema.nodes.code_block)); bind("Ctrl-m", (state: EditorState, dispatch: (tx: Transaction) => void) => { - dispatch(state.tr.replaceSelectionWith(schema.nodes.dashField.create({ fieldKey: "math" + Utils.GenerateGuid() }))); + dispatch(state.tr.replaceSelectionWith(schema.nodes.equation.create({ fieldKey: "math" + Utils.GenerateGuid() }))); }) for (let i = 1; i <= 6; i++) { diff --git a/src/client/views/nodes/formattedText/nodes_rts.ts b/src/client/views/nodes/formattedText/nodes_rts.ts index 5d9c8b56d..3bd41fa7d 100644 --- a/src/client/views/nodes/formattedText/nodes_rts.ts +++ b/src/client/views/nodes/formattedText/nodes_rts.ts @@ -242,6 +242,19 @@ export const nodes: { [index: string]: NodeSpec } = { } }, + equation: { + inline: true, + attrs: { + fieldKey: { default: "" }, + }, + group: "inline", + draggable: false, + toDOM(node) { + const attrs = { style: `width: ${node.attrs.width}, height: ${node.attrs.height}` }; + return ["div", { ...node.attrs, ...attrs }]; + } + }, + video: { inline: true, attrs: { -- cgit v1.2.3-70-g09d2 From 1b481cd441cc8bb200906b246b43e4bc5dc53b4e Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 2 Mar 2021 19:52:59 -0500 Subject: added a fitwidth toggle for lightbox. fixed _showCaption/setting _fields to undefined. updated documentView to use not having fitWidth set as a trigger for whether to treat a doc without nativeWidth/Height as if its width/height is that. --- src/client/documents/Documents.ts | 14 ++-- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/LightboxView.tsx | 5 ++ src/client/views/PropertiesButtons.tsx | 30 ++++++++- .../views/collections/CollectionStackingView.tsx | 37 ++++++----- .../CollectionMulticolumnView.tsx | 6 +- .../CollectionMultirowView.tsx | 16 ++--- src/client/views/nodes/DocumentView.tsx | 75 +++++++++++++--------- src/client/views/nodes/EquationBox.tsx | 11 ++-- src/client/views/nodes/VideoBox.tsx | 2 +- src/fields/Schema.ts | 5 +- src/fields/util.ts | 2 +- 12 files changed, 125 insertions(+), 80 deletions(-) (limited to 'src/client/views') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index e270d2ac8..f87c7185c 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -830,7 +830,7 @@ export namespace Docs { } export function KVPDocument(document: Doc, options: DocumentOptions = {}) { - return InstanceFromProto(Prototypes.get(DocumentType.KVP), document, { title: document.title + ".kvp", ...options }); + return InstanceFromProto(Prototypes.get(DocumentType.KVP), document, { _fitWidth: true, title: document.title + ".kvp", ...options }); } export function DocumentDocument(document?: Doc, options: DocumentOptions = {}) { @@ -860,23 +860,23 @@ export namespace Docs { } export function CarouselDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Carousel }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _fitWidth: true, ...options, _viewType: CollectionViewType.Carousel }); } export function Carousel3DDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Carousel3D }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _fitWidth: true, ...options, _viewType: CollectionViewType.Carousel3D }); } export function SchemaDocument(schemaHeaders: SchemaHeaderField[], documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaHeaders: schemaHeaders.length ? new List(schemaHeaders) : undefined, ...options, _viewType: CollectionViewType.Schema }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _fitWidth: true, schemaHeaders: schemaHeaders.length ? new List(schemaHeaders) : undefined, ...options, _viewType: CollectionViewType.Schema }); } export function TreeDocument(documents: Array, options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", dontRegisterChildViews: true, ...options, _viewType: CollectionViewType.Tree }, id); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _fitWidth: true, dontRegisterChildViews: true, ...options, _viewType: CollectionViewType.Tree }, id); } export function StackingDocument(documents: Array, options: DocumentOptions, id?: string, protoId?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", ...options, _viewType: CollectionViewType.Stacking }, id, undefined, protoId); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", _fitWidth: true, ...options, _viewType: CollectionViewType.Stacking }, id, undefined, protoId); } export function MulticolumnDocument(documents: Array, options: DocumentOptions) { @@ -926,7 +926,7 @@ export namespace Docs { export function DockDocument(documents: Array, config: string, options: DocumentOptions, id?: string) { const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { freezeChildren: "remove|add", treeViewDefaultExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id); - const tabs = TreeDocument(documents, { title: "On-Screen Tabs", freezeChildren: "remove|add", treeViewLockExpandedView: true, treeViewDefaultExpandedView: "data", system: true }); + const tabs = TreeDocument(documents, { title: "On-Screen Tabs", freezeChildren: "remove|add", treeViewLockExpandedView: true, treeViewDefaultExpandedView: "data", _fitWidth: true, system: true }); const all = TreeDocument([], { title: "Off-Screen Tabs", freezeChildren: "add", treeViewLockExpandedView: true, treeViewDefaultExpandedView: "data", system: true }); Doc.GetProto(inst).data = new List([tabs, all]); return inst; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 5b7394c42..1e3c0ba92 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -479,7 +479,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b SelectionManager.Views().map(dv => { const hgts = this._dragHeights.get(dv.layoutDoc); if (hgts && hgts.lowest < hgts.start && hgts.lowest <= 20) { - dv.nativeWidth > 0 && Doc.toggleNativeDimensions(dv.layoutDoc, dv.ContentScale(), dv.props.PanelWidth(), dv.props.PanelHeight()); + dv.effectiveNativeWidth > 0 && Doc.toggleNativeDimensions(dv.layoutDoc, dv.ContentScale(), dv.props.PanelWidth(), dv.props.PanelHeight()); if (dv.layoutDoc._autoHeight) dv.layoutDoc._autoHeight = false; setTimeout(() => dv.layoutDoc._autoHeight = true); } diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 15b98467c..3fc72c45c 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -247,6 +247,7 @@ export class LightboxView extends React.Component { ContainingCollectionDoc={undefined} renderDepth={0} /> + {this.navBtn(0, undefined, this.props.PanelHeight / 2 - 12.50, "chevron-left", () => LightboxView.LightboxDoc && LightboxView._history?.length ? "" : "none", e => { e.stopPropagation(); @@ -258,6 +259,10 @@ export class LightboxView extends React.Component { LightboxView.Next(); })} +
{ e.stopPropagation(); LightboxView.LightboxDoc!._fitWidth = !LightboxView.LightboxDoc!._fitWidth }}> + +
; } } diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index e9963bce9..e418a6f3c 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -260,7 +260,10 @@ export class PropertiesButtons extends React.Component<{}, {}> { @undoBatch @action setCaption = () => { - SelectionManager.Views().forEach(dv => dv.rootDoc._showCaption = dv.rootDoc._showCaption === undefined ? "caption" : undefined); + SelectionManager.Views().forEach(dv => { + dv.rootDoc._showCaption = dv.rootDoc._showCaption === undefined ? "caption" : undefined; + console.log("caption = " + dv.rootDoc._showCaption); + }); } @computed @@ -426,6 +429,14 @@ export class PropertiesButtons extends React.Component<{}, {}> { } } + @action @undoBatch + changeFitWidth = () => { + if (this.selectedDoc) { + if (SelectionManager.Views().length) SelectionManager.Views().forEach(dv => dv.rootDoc._fitWidth = !dv.rootDoc._fitWidth); + else this.selectedDoc._fitWidth = !this.selectedDoc._fitWidth; + } + } + @action @undoBatch changeClusters = () => { if (this.selectedDoc) { @@ -448,6 +459,20 @@ export class PropertiesButtons extends React.Component<{}, {}> {
; } + @computed + get fitWidthButton() { + const targetDoc = this.selectedDoc; + return !targetDoc ? (null) :
{this.selectedDoc?._fitWidth ? "Stop Fitting Width" : "Fit Width"}
} placement="top"> +
+
+ +
+
{this.selectedDoc?._fitWidth ? "unfit" : "fit"}
+
+
; + } + @undoBatch @action private makeMask = () => { @@ -521,6 +546,9 @@ export class PropertiesButtons extends React.Component<{}, {}> {
{this.fitContentButton}
+
+ {this.fitWidthButton} +
{this.maskButton}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index b5ce4b443..7152f4272 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -29,6 +29,7 @@ import "./CollectionStackingView.scss"; import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn"; import { CollectionSubView } from "./CollectionSubView"; import { CollectionViewType } from "./CollectionView"; +import { LightboxView } from "../LightboxView"; const _global = (window /* browser */ || global /* node */) as any; type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>; @@ -204,10 +205,10 @@ export class CollectionStackingView extends CollectionSubView this.getDocHeight(doc); - let dref: Opt; + let dref: Opt; const stackedDocTransform = () => this.getDocTransform(doc, dref); this._docXfs.push({ stackedDocTransform, width, height }); - return dref = r?.ContentDiv ? r.ContentDiv : undefined} + return dref = r || undefined} Document={doc} DataDoc={dataDoc || (!Doc.AreProtosEqual(doc[DataSym], doc) && doc[DataSym])} renderDepth={this.props.renderDepth + 1} @@ -247,18 +248,24 @@ export class CollectionStackingView extends CollectionSubView; } + getDocTransform(doc: Doc, dref?: DocumentView) { + const y = this._scroll; // required for document decorations to update when the text box container is scrolled + const { scale, translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv || undefined); + // the document view may center its contents and if so, will prepend that onto the screenToLocalTansform. so we have to subtract that off + return new Transform(- translateX - (dref?.centeringX || 0), - translateY - (dref?.centeringY || 0), 1).scale(this.props.ScreenToLocalTransform().Scale * (this.props.scaling?.() || 1)); + } getDocWidth(d?: Doc) { if (!d) return 0; - const layoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.()); - const nw = Doc.NativeWidth(layoutDoc); - return Math.min(nw && !this.layoutDoc._columnsFill ? d[WidthSym]() : Number.MAX_VALUE, this.columnWidth / this.numGroupColumns); + const childLayoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.()); + const nw = Doc.NativeWidth(childLayoutDoc) || (childLayoutDoc._fitWidth ? 0 : d[WidthSym]()); + return Math.min(nw && !this.layoutDoc._columnsFill ? (this.props.scaling?.() || 1) * d[WidthSym]() : Number.MAX_VALUE, this.columnWidth / this.numGroupColumns); } getDocHeight(d?: Doc) { if (!d) return 0; const childDataDoc = (!d.isTemplateDoc && !d.isTemplateForField && !d.PARAMS) ? undefined : this.props.DataDoc; const childLayoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.()); - const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc); - const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc); + const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (childLayoutDoc._fitWidth ? 0 : d[WidthSym]()); + const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (childLayoutDoc._fitWidth ? 0 : d[HeightSym]()); let wid = this.columnWidth / (this.isStackingView ? this.numGroupColumns : 1); if (!this.layoutDoc._columnsFill) wid = Math.min(wid, childLayoutDoc[WidthSym]()); const hllimit = NumCast(this.layoutDoc.childLimitHeight, -1); @@ -268,7 +275,7 @@ export class CollectionStackingView extends CollectionSubView this.isStackingView ? 1 : Math.max(1, Math.min(this.filteredChildren.length, Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap)))); return this.refList.splice(this.refList.indexOf(ref), 1)} - observeHeight={(ref) => { + unobserveHeight={ref => this.refList.splice(this.refList.indexOf(ref), 1)} + observeHeight={ref => { if (ref) { this.refList.push(ref); const doc = this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc; @@ -371,7 +378,9 @@ export class CollectionStackingView extends CollectionSubView NumCast(Doc.Layout(doc)._viewScale, 1) * Number(getComputedStyle(r).height.replace("px", ""))))); - this.props.setHeight(height * NumCast(Doc.Layout(doc)._viewScale, 1)); + if (!LightboxView.IsLightboxDocView(this.props.docViewPath())) { + this.props.setHeight(height * NumCast(Doc.Layout(doc)._viewScale, 1)); + } } })); this.observer.observe(ref); @@ -390,12 +399,6 @@ export class CollectionStackingView extends CollectionSubView; } - getDocTransform(doc: Doc, dref?: HTMLDivElement) { - const y = this._scroll; // required for document decorations to update when the text box container is scrolled - const { scale, translateX, translateY } = Utils.GetScreenTransform(dref); - return new Transform(-translateX, -translateY, 1).scale(this.props.ScreenToLocalTransform().Scale); - } - sectionMasonry = (heading: SchemaHeaderField | undefined, docList: Doc[], first: boolean) => { const key = this.pivotField; let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined; diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index e51417f64..d23f3309e 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -217,8 +217,8 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu Document={layout} DataDoc={layout.resolvedDataDoc as Doc} styleProvider={this.props.styleProvider} - layerProvider={undefined} - docViewPath={returnEmptyDoclist} + layerProvider={this.props.layerProvider} + docViewPath={this.props.docViewPath} LayoutTemplate={this.props.childLayoutTemplate} LayoutTemplateString={this.props.childLayoutString} freezeDimensions={this.props.childFreezeDimensions} @@ -257,7 +257,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu const collector: JSX.Element[] = []; for (let i = 0; i < childLayoutPairs.length; i++) { const { layout } = childLayoutPairs[i]; - const dxf = () => this.lookupIndividualTransform(layout).translate(-NumCast(Document._xMargin), -NumCast(Document._yMargin)); + const dxf = () => this.lookupIndividualTransform(layout).translate(-NumCast(Document._xMargin), -NumCast(Document._yMargin)).scale((this.props.scaling?.() || 1)); const width = () => this.lookupPixels(layout); const height = () => PanelHeight() - 2 * NumCast(Document._yMargin) - (BoolCast(Document.showWidthLabels) ? 20 : 0); collector.push( diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index d61a2bb72..641ae6ce1 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -217,8 +217,8 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) Document={layout} DataDoc={layout.resolvedDataDoc as Doc} styleProvider={this.props.styleProvider} - layerProvider={undefined} - docViewPath={returnEmptyDoclist} + layerProvider={this.props.layerProvider} + docViewPath={this.props.docViewPath} LayoutTemplate={this.props.childLayoutTemplate} LayoutTemplateString={this.props.childLayoutString} freezeDimensions={this.props.childFreezeDimensions} @@ -257,19 +257,13 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) const collector: JSX.Element[] = []; for (let i = 0; i < childLayoutPairs.length; i++) { const { layout } = childLayoutPairs[i]; - const dxf = () => this.lookupIndividualTransform(layout).translate(-NumCast(Document._xMargin), -NumCast(Document._yMargin)); + const dxf = () => this.lookupIndividualTransform(layout).translate(-NumCast(Document._xMargin), -NumCast(Document._yMargin)).scale((this.props.scaling?.() || 1)); const height = () => this.lookupPixels(layout); const width = () => PanelWidth() - 2 * NumCast(Document._xMargin) - (BoolCast(Document.showWidthLabels) ? 20 : 0); collector.push( -
+
{this.getDisplayDoc(layout, dxf, width, height)} - +
, { @computed get docViewPath() { return this.props.docViewPath ? [...this.props.docViewPath(), this] : [this]; } @computed get layoutDoc() { return Doc.Layout(this.Document, this.props.LayoutTemplate?.()); } - @computed get nativeWidth() { return this.docView?._componentView?.reverseNativeScaling?.() ? 0 : returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions)); } - @computed get nativeHeight() { return this.docView?._componentView?.reverseNativeScaling?.() ? 0 : returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions) || 0); } + @computed get nativeWidth() { + return this.docView?._componentView?.reverseNativeScaling?.() ? 0 : + returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions)); + } + @computed get nativeHeight() { + return this.docView?._componentView?.reverseNativeScaling?.() ? 0 : + returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, this.props.freezeDimensions)); + } + shouldNotScale = () => this.layoutDoc._fitWidth || [CollectionViewType.Docking, CollectionViewType.Tree].includes(this.Document._viewType as any); + @computed get effectiveNativeWidth() { return this.nativeWidth || (this.shouldNotScale() ? 0 : NumCast(this.layoutDoc.width)); } + @computed get effectiveNativeHeight() { return this.nativeHeight || (this.shouldNotScale() ? 0 : NumCast(this.layoutDoc.height)); } @computed get nativeScaling() { - if (this.nativeWidth && (this.layoutDoc?._fitWidth || this.props.PanelHeight() / this.nativeHeight > this.props.PanelWidth() / this.nativeWidth)) { - return this.props.PanelWidth() / this.nativeWidth; // width-limited or fitWidth + const minTextScale = this.Document.type === DocumentType.RTF ? 0.1 : 0; + if (this.effectiveNativeWidth && (this.layoutDoc?._fitWidth || this.props.PanelHeight() / this.effectiveNativeHeight > this.props.PanelWidth() / this.effectiveNativeWidth)) { + return Math.max(minTextScale, this.props.PanelWidth() / this.effectiveNativeWidth); // width-limited or fitWidth } - return this.nativeWidth && this.nativeHeight ? this.props.PanelHeight() / this.nativeHeight : 1; // height-limited or unscaled + return this.effectiveNativeWidth && this.effectiveNativeHeight ? Math.max(minTextScale, this.props.PanelHeight() / this.effectiveNativeHeight) : 1; // height-limited or unscaled } - @computed get panelWidth() { return this.nativeWidth ? this.nativeWidth * this.nativeScaling : this.props.PanelWidth(); } + @computed get panelWidth() { return this.effectiveNativeWidth ? this.effectiveNativeWidth * this.nativeScaling : this.props.PanelWidth(); } @computed get panelHeight() { - if (this.nativeHeight) { + if (this.effectiveNativeHeight) { return Math.min(this.props.PanelHeight(), this.props.Document._fitWidth ? - Math.max(NumCast(this.props.Document._height), NumCast(((this.props.Document.scrollHeight || 0) as number) * this.props.PanelWidth() / this.nativeWidth, this.props.PanelHeight())) : - this.nativeHeight * this.nativeScaling + Math.max(NumCast(this.props.Document._height), NumCast(((this.props.Document.scrollHeight || 0) as number) * this.props.PanelWidth() / this.effectiveNativeWidth, this.props.PanelHeight())) : + this.effectiveNativeHeight * this.nativeScaling ); } return this.props.PanelHeight(); } - @computed get Xshift() { return this.nativeWidth ? (this.props.PanelWidth() - this.nativeWidth * this.nativeScaling) / 2 : 0; } - @computed get YShift() { return this.nativeWidth && this.nativeHeight && Math.abs(this.Xshift) < 0.001 ? (this.props.PanelHeight() - this.nativeHeight * this.nativeScaling) / 2 : 0; } + @computed get Xshift() { return this.effectiveNativeWidth ? (this.props.PanelWidth() - this.effectiveNativeWidth * this.nativeScaling) / 2 : 0; } + @computed get Yshift() { return this.effectiveNativeWidth && this.effectiveNativeHeight && Math.abs(this.Xshift) < 0.001 ? (this.props.PanelHeight() - this.effectiveNativeHeight * this.nativeScaling) / 2 : 0; } @computed get centeringX() { return this.props.dontCenter?.includes("x") ? 0 : this.Xshift; } - @computed get centeringY() { return this.props.Document._fitWidth || this.props.dontCenter?.includes("y") ? 0 : this.YShift; } + @computed get centeringY() { return this.props.Document._fitWidth || this.props.dontCenter?.includes("y") ? 0 : this.Yshift; } toggleNativeDimensions = () => this.docView && Doc.toggleNativeDimensions(this.layoutDoc, this.docView.ContentScale, this.props.PanelWidth(), this.props.PanelHeight()); contentsActive = () => this.docView?.contentsActive(); @@ -1067,8 +1077,8 @@ export class DocumentView extends React.Component { docViewPathFunc = () => this.docViewPath; isSelected = (outsideReaction?: boolean) => SelectionManager.IsSelected(this, outsideReaction); select = (extendSelection: boolean) => SelectionManager.SelectView(this, !SelectionManager.Views().some(v => v.props.Document === this.props.ContainingCollectionDoc) && extendSelection); - NativeWidth = () => this.nativeWidth; - NativeHeight = () => this.nativeHeight; + NativeWidth = () => this.effectiveNativeWidth; + NativeHeight = () => this.effectiveNativeHeight; PanelWidth = () => this.panelWidth; PanelHeight = () => this.panelHeight; ContentScale = () => this.nativeScaling; @@ -1093,31 +1103,32 @@ export class DocumentView extends React.Component { render() { TraceMobx(); - const internalProps = { - ...this.props, - DocumentView: this.selfView, - viewPath: this.docViewPathFunc, - PanelWidth: this.PanelWidth, - PanelHeight: this.PanelHeight, - NativeWidth: this.NativeWidth, - NativeHeight: this.NativeHeight, - isSelected: this.isSelected, - select: this.select, - ContentScaling: this.ContentScale, - ScreenToLocalTransform: this.screenToLocalTransform, - focus: this.props.focus || emptyFunction, - bringToFront: emptyFunction, - }; + const xshift = this.props.Document.isInkMask ? InkingStroke.MaskDim : Math.abs(this.Xshift) <= 0.001 ? this.props.PanelWidth() : undefined; + const yshift = this.props.Document.isInkMask ? InkingStroke.MaskDim : Math.abs(this.Yshift) <= 0.001 ? this.props.PanelHeight() : undefined; return (
{!this.props.Document || !this.props.PanelWidth() ? (null) : (
0.001 ? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%` : this.props.PanelWidth(), - height: this.props.Document.isInkMask ? InkingStroke.MaskDim : Math.abs(this.YShift) > 0.001 ? this.props.Document._fitWidth ? `${this.panelHeight}px` : `${100 * this.nativeHeight / this.nativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%` : this.props.PanelHeight(), + width: xshift ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`, + height: yshift ?? this.props.Document._fitWidth ? `${this.panelHeight}px` : + `${100 * this.effectiveNativeHeight / this.effectiveNativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%`, }}> - this.docView = r)} /> + this.docView = r)} />
)}
); } diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx index 7f9fc342a..5bc73d5d9 100644 --- a/src/client/views/nodes/EquationBox.tsx +++ b/src/client/views/nodes/EquationBox.tsx @@ -56,10 +56,13 @@ export class EquationBox extends ViewBoxBaseComponent { this.dataDoc.text = str; - const _height = Number(getComputedStyle(this._ref.current!.element.current).height.replace("px", "")); - const _width = Number(getComputedStyle(this._ref.current!.element.current).width.replace("px", "")); - this.layoutDoc._width = Math.max(35, _width); - this.layoutDoc._height = Math.max(25, _height); + const style = this._ref.current && getComputedStyle(this._ref.current.element.current); + if (style) { + const _height = Number(style.height.replace("px", "")); + const _width = Number(style.width.replace("px", "")); + this.layoutDoc._width = Math.max(35, _width); + this.layoutDoc._height = Math.max(25, _height); + } } render() { TraceMobx(); diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 589a6dd24..6afc2258a 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -482,7 +482,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent this._playing; isActiveChild = () => this._isChildActive; - timelineWhenActiveChanged = (isActive: boolean) => this.props.whenActiveChanged(runInAction(() => this._isChildActive = isActive)); + timelineWhenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive)); timelineScreenToLocal = () => this.props.ScreenToLocalTransform().scale(this.scaling()).translate(0, -this.heightPercent / 100 * this.props.PanelHeight()); setAnchorTime = (time: number) => this.player!.currentTime = this.layoutDoc._currentTimecode = time; timelineHeight = () => this.props.PanelHeight() * (100 - this.heightPercent) / 100; diff --git a/src/fields/Schema.ts b/src/fields/Schema.ts index 4607e0fd5..78f8a6bfb 100644 --- a/src/fields/Schema.ts +++ b/src/fields/Schema.ts @@ -3,6 +3,7 @@ import { Doc, Field } from "./Doc"; import { ObjectField } from "./ObjectField"; import { RefField } from "./RefField"; import { SelfProxy } from "./FieldSymbols"; +import { List } from "./List"; type AllToInterface = { 1: ToInterface> & AllToInterface>, @@ -67,9 +68,9 @@ export function makeInterface(...schemas: T): InterfaceFu return function (doc?: Doc | Doc[]) { if (doc instanceof Doc || doc === undefined) { return fn(doc || new Doc); - } else { + } else if (doc instanceof List) { return doc.map(fn); - } + } else return {}; }; } diff --git a/src/fields/util.ts b/src/fields/util.ts index 7955fc9fb..36c765dd0 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -289,7 +289,7 @@ export function setter(target: any, in_prop: string | symbol | number, value: an // console.log(prop + " is deprecated - switch to _" + prop); // prop = "_" + prop; // } - if (!prop.startsWith("__") && value !== undefined) prop = prop.substring(1); + if (!prop.startsWith("__")) prop = prop.substring(1); if (target.__LAYOUT__) { target.__LAYOUT__[prop] = value; return true; -- cgit v1.2.3-70-g09d2