From 57c1b8235b26a1b6a315922b4dc2926e1e597674 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 13 May 2022 18:17:10 -0400
Subject: removed layerProvider functionality.

---
 src/client/views/collections/CollectionStackingView.tsx | 2 --
 1 file changed, 2 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 509005b45..4338dedcc 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -222,7 +222,6 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
             PanelWidth={width}
             PanelHeight={height}
             styleProvider={this.styleProvider}
-            layerProvider={this.props.layerProvider}
             docViewPath={this.props.docViewPath}
             fitWidth={this.props.childFitWidth}
             isContentActive={emptyFunction}
@@ -543,7 +542,6 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                     renderDepth={this.props.renderDepth}
                     focus={emptyFunction}
                     styleProvider={this.props.styleProvider}
-                    layerProvider={this.props.layerProvider}
                     docViewPath={returnEmptyDoclist}
                     whenChildContentsActiveChanged={emptyFunction}
                     bringToFront={emptyFunction}
-- 
cgit v1.2.3-70-g09d2


From 6df80c76b4046ef1ac9e98e52f766dfaf540ead2 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 20 May 2022 12:51:51 -0400
Subject: removed enumerables field stuff which was hacky and never used. 
 cleaned up some of currentUserUtils initialiazation.  fixed treeView sorting
 for 'none" which fixes problem with slide template.

---
 src/client/documents/Documents.ts                  |  24 --
 src/client/util/CurrentUserUtils.ts                | 242 +++++----------------
 .../views/collections/CollectionStackingView.tsx   |   1 -
 src/client/views/collections/TreeView.tsx          |   2 +-
 src/client/views/nodes/ComparisonBox.tsx           |   2 +-
 .../views/nodes/formattedText/DashFieldView.tsx    |  14 --
 6 files changed, 57 insertions(+), 228 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 2dd8de089..4be9674f7 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1406,30 +1406,6 @@ export namespace DocUtils {
         return undefined;
     }
 
-    export async function addFieldEnumerations(doc: Opt<Doc>, enumeratedFieldKey: string, enumerations: { title: string, _backgroundColor?: string, color?: string }[]) {
-        let optionsCollection = await DocServer.GetRefField(enumeratedFieldKey);
-        if (!(optionsCollection instanceof Doc)) {
-            optionsCollection = Docs.Create.StackingDocument([], { title: `${enumeratedFieldKey} field set`, system: true }, enumeratedFieldKey);
-            Doc.AddDocToList((Doc.UserDoc().fieldTypes as Doc), "data", optionsCollection as Doc);
-        }
-        const options = optionsCollection as Doc;
-        const targetDoc = doc && Doc.GetProto(Cast(doc.rootDocument, Doc, null) || doc);
-        const docFind = `options.data?.find(doc => doc.title === (this.rootDocument||this)["${enumeratedFieldKey}"])?`;
-        targetDoc && (targetDoc.backgroundColor = ComputedField.MakeFunction(docFind + `._backgroundColor || "white"`, undefined, { options }));
-        targetDoc && (targetDoc.color = ComputedField.MakeFunction(docFind + `.color || "black"`, undefined, { options }));
-        targetDoc && (targetDoc.borderRounding = ComputedField.MakeFunction(docFind + `.borderRounding`, undefined, { options }));
-        enumerations.map(enumeration => {
-            const found = DocListCast(options.data).find(d => d.title === enumeration.title);
-            if (found) {
-                found._backgroundColor = enumeration._backgroundColor || found._backgroundColor;
-                found._color = enumeration.color || found._color;
-            } else {
-                Doc.AddDocToList(options, "data", Docs.Create.TextDocument(enumeration.title, { ...enumeration, system: true }));
-            }
-        });
-        return optionsCollection;
-    }
-
     // /**
     //  * 
     //  * @param dms Degree Minute Second format exif gps data
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 8fed6e940..e0580d3c4 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -75,201 +75,68 @@ export class CurrentUserUtils {
     @observable public static searchPanelWidth: number = 0;
 
     // sets up the default User Templates - slideView,  headerView
-    static setupUserTemplateButtons(doc: Doc) {
-        // Prototype for mobile button (not sure if 'Advanced Item Prototypes' is ideal location)
-        if (doc["template-mobile-button"] === undefined) {
-            const queryTemplate = this.mobileButton({
-                title: "NEW MOBILE BUTTON",
-                onClick: undefined,
-            },
-                [this.createToolButton({
-                    ignoreClick: true,
-                    icon: "mobile",
-                    btnType: ButtonType.ToolButton,
-                    backgroundColor: "transparent"
-                }),
-                this.mobileTextContainer({},
-                    [this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")])]);
-            doc["template-mobile-button"] = CurrentUserUtils.createToolButton({
-                onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
-                dragFactory: new PrefetchProxy(queryTemplate) as any as Doc, title: "mobile button", icon: "mobile", btnType: ButtonType.ToolButton,
-            });
-        }
-
-        if (doc["template-button-slides"] === undefined) {
-            const slideTemplate = Docs.Create.MultirowDocument(
-                [
-                    Docs.Create.MulticolumnDocument([], { title: "data", _height: 200, system: true }),
-                    Docs.Create.TextDocument("", { title: "text", _height: 100, system: true, _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize) })
-                ],
-                { _width: 400, _height: 300, title: "slideView", _xMargin: 3, _yMargin: 3, system: true }
-            );
-            slideTemplate.isTemplateDoc = makeTemplate(slideTemplate);
-            doc["template-button-slides"] = CurrentUserUtils.createToolButton({
-                onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
-                dragFactory: new PrefetchProxy(slideTemplate) as any as Doc, title: "presentation slide", icon: "address-card",
-                btnType: ButtonType.ToolButton
-            });
-        }
-
-        if (doc["template-button-link"] === undefined) {  // set _backgroundColor to transparent to prevent link dot from obscuring document it's attached to.
-            const linkTemplate = Doc.MakeDelegate(Docs.Create.TextDocument(" ", { title: "header", _autoHeight: true, system: true }, "header")); // text needs to be a space to allow templateText to be created
-            linkTemplate.system = true;
-            Doc.GetProto(linkTemplate).layout =
-                "<div>" +
-                "    <FormattedTextBox {...props} dontSelectOnLoad={'true'} height='{this._headerHeight||75}px' ignoreAutoHeight={'true'} background='{this._headerColor||`lightGray`}' fieldKey={'header'}/>" +
-                "    <FormattedTextBox {...props} position='absolute' top='{(this._headerHeight||75)*scale}px' height='calc({100/scale}% - {this._headerHeight||75}px)' fieldKey={'text'}/>" +
-                "</div>";
-            (linkTemplate.proto as Doc).isTemplateDoc = makeTemplate(linkTemplate.proto as Doc, true, "linkView");
-
-            const rtf2 = {
-                doc: {
-                    type: "doc", content: [
-                        {
-                            type: "paragraph",
-                            content: [{
-                                type: "dashField",
-                                attrs: {
-                                    fieldKey: "src",
-                                    hideKey: false
-                                }
-                            }]
-                        },
-                        { type: "paragraph" },
-                        {
-                            type: "paragraph",
-                            content: [{
-                                type: "dashField",
-                                attrs: {
-                                    fieldKey: "dst",
-                                    hideKey: false
-                                }
-                            }]
-                        }]
+    static setupExperimentalTemplateButtons(doc: Doc) {
+        if (doc["template-experimental-buttons"] === undefined) {
+            const requiredTypeNameFields = [
+                {
+                    type: "slide", icon: "address-card", template: Docs.Create.MultirowDocument(
+                        [
+                            Docs.Create.MulticolumnDocument([], { title: "data", _height: 200, system: true }),
+                            Docs.Create.TextDocument("", { title: "text", _height: 100, system: true, _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize) })
+                        ],
+                        { _width: 400, _height: 300, title: "slideView", _xMargin: 3, _yMargin: 3, system: true }
+                    )
                 },
-                selection: { type: "text", anchor: 1, head: 1 },
-                storedMarks: []
-            };
-            linkTemplate.header = new RichTextField(JSON.stringify(rtf2), "");
-
-            doc["template-button-link"] = CurrentUserUtils.createToolButton({
-                onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
-                dragFactory: new PrefetchProxy(linkTemplate) as any as Doc, title: "link view", icon: "window-maximize", system: true,
-                btnType: ButtonType.ToolButton
+                {
+                    type: "mobile", icon: "mobile", template: this.mobileButton({ title: "NEW MOBILE BUTTON", onClick: undefined, },
+                        [this.createToolButton({ ignoreClick: true, icon: "mobile", btnType: ButtonType.ToolButton, backgroundColor: "transparent" }),
+                        this.mobileTextContainer({},
+                            [this.mobileButtonText({}, "NEW MOBILE BUTTON"), this.mobileButtonInfo({}, "You can customize this button and make it your own.")])
+                        ]
+                    )
+                },
+            ];
+            const requiredTypes = requiredTypeNameFields.map(({ type, icon, template }) => {
+                if (doc[`template-button-${type}`] === undefined) {
+                    template.isTemplateDoc = makeTemplate(template);
+                    doc[`template-button-${type}`] = CurrentUserUtils.createToolButton({
+                        onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
+                        dragFactory: new PrefetchProxy(template) as any as Doc,
+                        title: type,
+                        icon,
+                        btnType: ButtonType.ToolButton,
+                    });
+                }
+                return doc[`template-button-${type}`] as Doc;
             });
-        }
 
-        // if (doc["template-button-switch"] === undefined) {
-        //     const { FreeformDocument, MulticolumnDocument, TextDocument } = Docs.Create;
-
-        //     const yes = FreeformDocument([], { title: "yes", _height: 35, _width: 50, _dimUnit: DimUnit.Pixel, _dimMagnitude: 40, system: true });
-        //     const name = TextDocument("name", { title: "name", _height: 35, _width: 70, _dimMagnitude: 1, system: true });
-        //     const no = FreeformDocument([], { title: "no", _height: 100, _width: 100, system: true });
-        //     const labelTemplate = {
-        //         doc: {
-        //             type: "doc", content: [{
-        //                 type: "paragraph",
-        //                 content: [{ type: "dashField", attrs: { fieldKey: "PARAMS", hideKey: true } }]
-        //             }]
-        //         },
-        //         selection: { type: "text", anchor: 1, head: 1 },
-        //         storedMarks: []
-        //     };
-        //     Doc.GetProto(name).text = new RichTextField(JSON.stringify(labelTemplate), "PARAMS");
-        //     Doc.GetProto(yes).backgroundColor = ComputedField.MakeFunction("self[this.PARAMS] ? 'green':'red'");
-        //     // Doc.GetProto(no).backgroundColor = ComputedField.MakeFunction("!self[this.PARAMS] ? 'red':'white'");
-        //     // Doc.GetProto(yes).onClick = ScriptField.MakeScript("self[this.PARAMS] = true");
-        //     Doc.GetProto(yes).onClick = ScriptField.MakeScript("self[this.PARAMS] = !self[this.PARAMS]");
-        //     // Doc.GetProto(no).onClick = ScriptField.MakeScript("self[this.PARAMS] = false");
-        //     const box = MulticolumnDocument([/*no, */ yes, name], { title: "value", _width: 120, _height: 35, system: true });
-        //     box.isTemplateDoc = makeTemplate(box, true, "switch");
-
-        //     doc["template-button-switch"] = CurrentUserUtils.createToolButton({
-        //         onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'),
-        //         dragFactory: new PrefetchProxy(box) as any as Doc, title: "data switch", icon: "toggle-on", system: true,
-        //         btnType: ButtonType.ToolButton
-        //     });
-        // }
-
-        const requiredTypes = [
-            doc["template-button-slides"] as Doc,
-            doc["template-mobile-button"] as Doc,
-            doc["template-button-link"] as Doc,
-            //doc["template-button-switch"] as Doc]
-        ];
-        if (doc["template-buttons"] === undefined) {
-            doc["template-buttons"] = new PrefetchProxy(Docs.Create.MasonryDocument(requiredTypes, {
-                title: "Advanced Item Prototypes", _xMargin: 0, _showTitle: "title", _chromeHidden: true,
+            doc["template-experimental-buttons"] = new PrefetchProxy(Docs.Create.MasonryDocument(requiredTypes, {
+                title: "Experimental Tools", _xMargin: 0, _showTitle: "title", _chromeHidden: true,
                 hidden: ComputedField.MakeFunction("IsNoviceMode()") as any,
                 _stayInCollection: true, _hideContextMenu: true, _forceActive: true,
                 _autoHeight: true, _width: 500, _height: 300, _fitWidth: true, _columnWidth: 35, ignoreClick: true, _lockedPosition: true,
                 dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), system: true
             }));
-        } else {
-            const curButnTypes = Cast(doc["template-buttons"], Doc, null);
-            DocListCastAsync(curButnTypes.data).then(async curBtns => {
-                curBtns && await Promise.all(curBtns);
-                requiredTypes.map(btype => Doc.AddDocToList(curButnTypes, "data", btype));
-            });
         }
-        return doc["template-buttons"] as Doc;
+        return doc["template-experimental-buttons"] as Doc;
     }
 
     // setup the different note type skins
     static setupNoteTemplates(doc: Doc) {
-        if (doc["template-note-Note"] === undefined) {
-            const noteView = Docs.Create.TextDocument("", {
-                title: "text", isTemplateDoc: true, backgroundColor: "yellow", system: true, icon: "sticky-note",
-                _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
-            });
-            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", backgroundColor: "pink", system: true, icon: "lightbulb",
-                _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
-            });
-            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", backgroundColor: "lightblue", system: true, icon: "book-open",
-                _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
-            });
-            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", backgroundColor: "orange", _autoHeight: false, _height: 100, _showCaption: "caption",
-        //         layout: FormattedTextBox.LayoutString("Todo"), caption: RichTextField.DashField("taskStatus"), system: true,
-        //         _fontFamily: StrCast(Doc.UserDoc()._fontFamily), _fontSize: StrCast(Doc.UserDoc()._fontSize),
-        //     });
-        //     noteView.isTemplateDoc = makeTemplate(noteView, true, "Todo");
-        //     doc["template-note-Todo"] = new PrefetchProxy(noteView);
-        // }
-        // const taskStatusValues = [
-        //     { title: "todo", _backgroundColor: "blue", color: "white", system: true },
-        //     { title: "in progress", _backgroundColor: "yellow", color: "black", system: true },
-        //     { title: "completed", _backgroundColor: "green", color: "white", system: true }
-        // ];
-        // if (doc.fieldTypes === undefined) {
-        //     doc.fieldTypes = Docs.Create.TreeDocument([], { title: "field enumerations", system: true });
-        //     DocUtils.addFieldEnumerations(Doc.GetProto(doc["template-note-Todo"] as any as Doc), "taskStatus", taskStatusValues);
-        // }
-
         if (doc["template-notes"] === undefined) {
-            doc["template-notes"] = new PrefetchProxy(Docs.Create.TreeDocument([doc["template-note-Note"] as any as Doc, doc["template-note-Idea"] as any as Doc, doc["template-note-Topic"] as any as Doc], // doc["template-note-Todo"] as any as Doc],
-                { title: "Note Layouts", _height: 75, system: true }));
-        } else {
-            const curNoteTypes = Cast(doc["template-notes"], Doc, null);
-            const requiredTypes = [doc["template-note-Note"] as any as Doc, doc["template-note-Idea"] as any as Doc, doc["template-note-Topic"] as any as Doc];//, doc["template-note-Todo"] as any as Doc];
-            DocListCastAsync(curNoteTypes.data).then(async curNotes => {
-                curNotes && await Promise.all(curNotes);
-                requiredTypes.map(ntype => Doc.AddDocToList(curNoteTypes, "data", ntype));
-            });
+            const requiredTypeNameFields = [
+                { type: "Note", backgroundColor: "yellow", icon: "sticky-note" },
+                { type: "Idea", backgroundColor: "pink", icon: "lightbulb" },
+                { type: "Topic", backgroundColor: "lightblue", icon: "book-open" }];
+            const requiredTypes = requiredTypeNameFields.map(({ type, backgroundColor, icon }) =>
+                doc[`template-note-${type}`] as Doc ??
+                (() => {
+                    const noteView = Docs.Create.TextDocument("", { title: "text", backgroundColor, system: true, icon });
+                    noteView.isTemplateDoc = makeTemplate(noteView, true, type);
+                    return doc[`template-note-${type}`] = new PrefetchProxy(noteView);
+                })());
+
+            doc["template-notes"] = new PrefetchProxy(Docs.Create.TreeDocument(requiredTypes, { title: "Note Layouts", _height: 75, system: true }));
         }
 
         return doc["template-notes"] as Doc;
@@ -277,11 +144,12 @@ export class CurrentUserUtils {
 
     // creates Note templates, and initial "user" templates
     static setupDocTemplates(doc: Doc) {
-        const noteTemplates = CurrentUserUtils.setupNoteTemplates(doc);
-        const userTemplateBtns = CurrentUserUtils.setupUserTemplateButtons(doc);
-        const clickTemplates = CurrentUserUtils.setupClickEditorTemplates(doc);
         if (doc.templateDocs === undefined) {
-            doc.templateDocs = new PrefetchProxy(Docs.Create.TreeDocument([noteTemplates, userTemplateBtns, clickTemplates], {
+            doc.templateDocs = new PrefetchProxy(Docs.Create.TreeDocument([
+                CurrentUserUtils.setupNoteTemplates(doc),
+                CurrentUserUtils.setupExperimentalTemplateButtons(doc),
+                CurrentUserUtils.setupClickEditorTemplates(doc)
+            ], {
                 title: "template layouts", _xMargin: 0, system: true,
                 dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name })
             }));
@@ -717,7 +585,7 @@ export class CurrentUserUtils {
     static async setupToolsBtnPanel(doc: Doc) {
         // setup a masonry view of all he creators
         const creatorBtns = await CurrentUserUtils.setupCreatorButtons(doc);
-        const templateBtns = CurrentUserUtils.setupUserTemplateButtons(doc);
+        const templateBtns = CurrentUserUtils.setupExperimentalTemplateButtons(doc);
 
         doc["tabs-button-tools"] = undefined;
 
@@ -1260,7 +1128,7 @@ export class CurrentUserUtils {
         doc.noviceMode = doc.noviceMode === undefined ? "true" : doc.noviceMode;
         doc.title = Doc.CurrentUserEmail;
         doc._raiseWhenDragged = true;
-        doc._showLabel = false;
+        doc._showLabel = true;
         doc._showMenuLabel = true;
         doc.textAlign = StrCast(doc.textAlign, "left");
         doc.activeInkColor = StrCast(doc.activeInkColor, "rgb(0, 0, 0)");
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 4338dedcc..4630b3bf2 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -482,7 +482,6 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         if (value && this.columnHeaders) {
             const schemaHdrField = new SchemaHeaderField(value);
             this.columnHeaders.push(schemaHdrField);
-            DocUtils.addFieldEnumerations(undefined, this.pivotField, [{ title: value, _backgroundColor: "schemaHdrField.color" }]);
             return true;
         }
         return false;
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index c004b4d49..65f8fe248 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -895,7 +895,7 @@ export class TreeView extends React.Component<TreeViewProps> {
             childDocs = childDocs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result);
         }
 
-        const docs = TreeView.sortDocs(childDocs, StrCast(containerCollection.treeViewSortCriterion));
+        const docs = TreeView.sortDocs(childDocs, StrCast(containerCollection.treeViewSortCriterion, TreeSort.None));
         const rowWidth = () => panelWidth() - treeBulletWidth();
         const treeViewRefs = new Map<Doc, TreeView | undefined>();
         return docs.filter(child => child instanceof Doc).map((child, i) => {
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index 49cd39f43..5ea6d567a 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -76,7 +76,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
         const clearButton = (which: string) => {
             return <div className={`clear-button ${which}`}
                 onPointerDown={e => e.stopPropagation()} // prevent triggering slider movement in registerSliding 
-                onClick={e => this.clearDoc(e, `compareBox-${which}`)}>
+                onClick={e => this.clearDoc(e, which)}>
                 <FontAwesomeIcon className={`clear-button ${which}`} icon={"times"} size="sm" />
             </div>;
         };
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 34908e54b..1a8352b72 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -58,7 +58,6 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna
     _textBoxDoc: Doc;
     _fieldKey: string;
     _fieldStringRef = React.createRef<HTMLSpanElement>();
-    @observable _showEnumerables: boolean = false;
     @observable _dashDoc: Doc | undefined;
 
     constructor(props: IDashFieldViewInternal) {
@@ -110,7 +109,6 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna
                         r?.addEventListener("keydown", e => this.fieldSpanKeyDown(e, r));
                         r?.addEventListener("blur", e => r && this.updateText(r.textContent!, false));
                         r?.addEventListener("pointerdown", action((e) => {
-                            this._showEnumerables = true;
                             e.stopPropagation();
                         }));
                     }} >
@@ -124,7 +122,6 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna
     @action
     fieldSpanKeyDown = (e: KeyboardEvent, span: HTMLSpanElement) => {
         if (e.key === "Enter") {  // handle the enter key by "submitting" the current text to Dash's database. 
-            e.ctrlKey && DocUtils.addFieldEnumerations(this._textBoxDoc, this._fieldKey, [{ title: span.textContent! }]);
             this.updateText(span.textContent!, true);
             e.preventDefault();// prevent default to avoid a newline from being generated and wiping out this field view
         }
@@ -142,7 +139,6 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna
 
     @action
     updateText = (nodeText: string, forceMatch: boolean) => {
-        this._showEnumerables = false;
         if (nodeText) {
             const newText = nodeText.startsWith(":=") || nodeText.startsWith("=:=") ? ":=-computed-" : nodeText;
 
@@ -154,7 +150,6 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna
                 (options instanceof Doc) && DocListCast(options.data).forEach(opt => (forceMatch ? StrCast(opt.title).startsWith(newText) : StrCast(opt.title) === newText) && (modText = StrCast(opt.title)));
                 if (modText) {
                     //  elementfieldSpan.innerHTML = this._dashDoc![this._fieldKey as string] = modText;
-                    DocUtils.addFieldEnumerations(this._textBoxDoc, this._fieldKey, []);
                     Doc.SetInPlace(this._dashDoc!, this._fieldKey, modText, true);
                 } // if the text starts with a ':=' then treat it as an expression by making a computed field from its value storing it in the key
                 else if (nodeText.startsWith(":=")) {
@@ -178,13 +173,6 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna
         }
     }
 
-    // display a collection of all the enumerable values for this field
-    onPointerDownEnumerables = async (e: any) => {
-        e.stopPropagation();
-        const collview = await DocUtils.addFieldEnumerations(this._textBoxDoc, this._fieldKey, [{ title: this._fieldKey }]);
-        collview instanceof Doc && this.props.tbox.props.addDocTab(collview, "add:right");
-    }
-
 
     // clicking on the label creates a pivot view collection of all documents
     // in the same collection.  The pivot field is the fieldKey of this label
@@ -220,8 +208,6 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna
 
             {this.props.fieldKey.startsWith("#") ? (null) : this.fieldValueContent}
 
-            {!this._showEnumerables ? (null) : <div className="dashFieldView-enumerables" onPointerDown={this.onPointerDownEnumerables} />}
-
         </div >;
     }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From a01cd55030f549b1c4c207d23731a00e689989c3 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 25 May 2022 15:18:46 -0400
Subject: variety of small fixes for text / sharing.   made typed text default
 to 35 height so that  when shared it doesn't start big and jump to small. 
 changed permissions to be private until an Acl is set - this prevents private
 docs from flicking on momentarily when shared since fields are not
 distributed atomically.  added Shift/Alt/Ctrl Enter for freeform and stacking
 views to create neighboring docs.  fixed first typed char of text to have a
 user_mark. made shared text doc header overlap to prevent scrolling.

---
 src/client/DocServer.ts                            | 60 ++++++++++------------
 src/client/documents/Documents.ts                  |  2 +-
 src/client/util/CurrentUserUtils.ts                |  2 +-
 src/client/views/MainView.tsx                      |  4 +-
 src/client/views/StyleProvider.tsx                 |  5 +-
 .../views/collections/CollectionStackingView.tsx   | 22 ++++++++
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  2 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx | 16 +++---
 .../formattedText/ProsemirrorExampleTransfer.ts    | 14 +++--
 src/fields/util.ts                                 |  7 ++-
 10 files changed, 77 insertions(+), 57 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index e498a7cca..dbc4783d8 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -364,40 +364,36 @@ export namespace DocServer {
                 const proms: Promise<void>[] = [];
                 runInAction(() => {
                     for (const field of fields) {
-                        if (field !== undefined && field !== null && !_cache[field.id]) {
+                        const cached = _cache[field.id];
+                        if (!cached) {
                             // deserialize
-                            const cached = _cache[field.id];
-                            if (!cached) {
-                                const prom = SerializationHelper.Deserialize(field).then(deserialized => {
-                                    fieldMap[field.id] = deserialized;
-
-                                    //overwrite or delete any promises (that we inserted as flags
-                                    // to indicate that the field was in the process of being fetched). Now everything
-                                    // should be an actual value within or entirely absent from the cache.
-                                    if (deserialized !== undefined) {
-                                        _cache[field.id] = deserialized;
-                                    } else {
-                                        delete _cache[field.id];
-                                    }
-                                    return deserialized;
-                                });
-                                // 4) here, for each of the documents we've requested *ourselves* (i.e. weren't promises or found in the cache)
-                                // we set the value at the field's id to a promise that will resolve to the field. 
-                                // When we find that promises exist at keys in the cache, THIS is where they were set, just by some other caller (method).
-                                // The mapping in the .then call ensures that when other callers await these promises, they'll
-                                // get the resolved field
-                                _cache[field.id] = prom;
-
-                                // adds to a list of promises that will be awaited asynchronously
-                                proms.push(prom);
-                            } else if (cached instanceof Promise) {
-                                proms.push(cached as any);
-                            }
-                        } else if (_cache[field.id] instanceof Promise) {
-                            proms.push(_cache[field.id] as any);
-                            (_cache[field.id] as any).then((f: any) => fieldMap[field.id] = f);
+                            const prom = SerializationHelper.Deserialize(field).then(deserialized => {
+                                fieldMap[field.id] = deserialized;
+
+                                //overwrite or delete any promises (that we inserted as flags
+                                // to indicate that the field was in the process of being fetched). Now everything
+                                // should be an actual value within or entirely absent from the cache.
+                                if (deserialized !== undefined) {
+                                    _cache[field.id] = deserialized;
+                                } else {
+                                    delete _cache[field.id];
+                                }
+                                return deserialized;
+                            });
+                            // 4) here, for each of the documents we've requested *ourselves* (i.e. weren't promises or found in the cache)
+                            // we set the value at the field's id to a promise that will resolve to the field. 
+                            // When we find that promises exist at keys in the cache, THIS is where they were set, just by some other caller (method).
+                            // The mapping in the .then call ensures that when other callers await these promises, they'll
+                            // get the resolved field
+                            _cache[field.id] = prom;
+
+                            // adds to a list of promises that will be awaited asynchronously
+                            proms.push(prom);
+                        } else if (cached instanceof Promise) {
+                            proms.push(cached as any);
+                            cached.then((f: any) => fieldMap[field.id] = f);
                         } else if (field) {
-                            proms.push(_cache[field.id] as any);
+                            proms.push(cached as any);
                             fieldMap[field.id] = DocServer.GetCachedRefField(field.id) || field;
                         }
                     }
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index c3b6953b5..ed37c48dc 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -369,7 +369,7 @@ export namespace Docs {
             [DocumentType.RTF, {
                 layout: { view: FormattedTextBox, dataField: "text" },
                 options: {
-                    _height: 150, _xMargin: 10, _yMargin: 10, nativeDimModifiable: true, nativeHeightUnfrozen: true, treeViewGrowsHorizontally: true,
+                    _height: 35, _xMargin: 10, _yMargin: 10, nativeDimModifiable: true, nativeHeightUnfrozen: true, treeViewGrowsHorizontally: true,
                     links: "@links(self)"
                 }
             }],
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index e4dc175bd..436237d6c 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -1184,7 +1184,7 @@ export class CurrentUserUtils {
     public static GetNewTextDoc(title: string, x: number, y: number, width?: number, height?: number, noMargins?: boolean, annotationOn?: Doc, maxHeight?: number, backgroundColor?: string) {
         const tbox = Docs.Create.TextDocument("", {
             _xMargin: noMargins ? 0 : undefined, _yMargin: noMargins ? 0 : undefined, annotationOn, docMaxAutoHeight: maxHeight, backgroundColor: backgroundColor,
-            _width: width || 200, _height: height || 100, x: x, y: y, _fitWidth: true, _autoHeight: true, title
+            _width: width || 200, _height: 35, x: x, y: y, _fitWidth: true, _autoHeight: true, title
         });
         const template = Doc.UserDoc().defaultTextLayout;
         if (template instanceof Doc) {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 183efc944..ff2857739 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -120,8 +120,8 @@ export class MainView extends React.Component {
         }
         this._sidebarContent.proto = undefined;
         if (!MainView.Live) {
-            DocServer.setPlaygroundFields(["dataTransition", "treeViewOpen", "autoHeight", "showSidebar", "sidebarWidthPercent", "viewTransition",
-                "panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "text-scrollHeight", "text-height", "hideMinimap",
+            DocServer.setPlaygroundFields(["dataTransition", "treeViewOpen", "showSidebar", "sidebarWidthPercent", "viewTransition",
+                "panX", "panY", "nativeWidth", "nativeHeight", "text-scrollHeight", "text-height", "hideMinimap",
                 "viewScale", "scrollTop", "hidden", "curPage", "viewType", "chromeHidden", "nativeWidth"]); // can play with these fields on someone else's
         }
         DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg)));
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index c44443264..553f84a67 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -70,6 +70,7 @@ export function wavyBorderPath(pw: number, ph: number, inset: number = 0.05) {
 // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab
 // 
 export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string): any {
+    const remoteDocHeader = "author;creationDate;noMargin";
     const docProps = testDocProps(props) ? props : undefined;
     const selected = property.includes(":selected");
     const isCaption = property.includes(":caption");
@@ -111,7 +112,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
                 props?.showTitle?.() ||
                 (!Doc.IsSystem(doc) && [DocumentType.COL, DocumentType.LABEL, DocumentType.RTF, DocumentType.IMG, DocumentType.VID].includes(doc.type as any) ?
                     (doc.author === Doc.CurrentUserEmail ? StrCast(Doc.UserDoc().showTitle) :
-                        "author;creationDate") : "")) || "");
+                        remoteDocHeader) : "")) || "");
         case StyleProp.Color:
             if (MainView.Instance.LastButton === doc) return Colors.DARK_GRAY;
             const docColor: Opt<string> = StrCast(doc?.[fieldKey + "color"], StrCast(doc?._color));
@@ -126,7 +127,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
         case StyleProp.BorderPath: return comicStyle() && props?.renderDepth && doc?.type !== DocumentType.INK ? { path: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0), fill: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0, .08), width: 3 } : { path: undefined, width: 0 };
         case StyleProp.JitterRotation: return comicStyle() ? random(-1, 1, NumCast(doc?.x), NumCast(doc?.y)) * ((props?.PanelWidth() || 0) > (props?.PanelHeight() || 0) ? 5 : 10) : 0;
         case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._viewType as any) ||
-            doc?.type === DocumentType.RTF || doc?.type === DocumentType.LABEL) && showTitle() && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0;
+            (doc?.type === DocumentType.RTF && !showTitle()?.includes("noMargin")) || doc?.type === DocumentType.LABEL) && showTitle() && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0;
         case StyleProp.BackgroundColor: {
             if (MainView.Instance.LastButton === doc) return Colors.LIGHT_GRAY;
             let docColor: Opt<string> =
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 4630b3bf2..dddae4a34 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -28,6 +28,8 @@ import "./CollectionStackingView.scss";
 import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn";
 import { CollectionSubView } from "./CollectionSubView";
 import { CollectionViewType } from "./CollectionView";
+import { FieldViewProps } from "../nodes/FieldView";
+import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox";
 const _global = (window /* browser */ || global /* node */) as any;
 
 
@@ -207,6 +209,25 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         }
         return this.props.styleProvider?.(doc, props, property);
     }
+    @undoBatch
+    @action
+    onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
+        const docView = fieldProps.DocumentView?.();
+        if (docView && ["Enter"].includes(e.key) && e.ctrlKey) {
+            e.stopPropagation?.();
+            const below = !e.altKey && e.key !== "Tab";
+            const layoutKey = StrCast(docView.LayoutFieldKey);
+            const newDoc = Doc.MakeCopy(docView.rootDoc, true);
+            const dataField = docView.rootDoc[Doc.LayoutFieldKey(newDoc)];
+            newDoc[DataSym][Doc.LayoutFieldKey(newDoc)] = dataField === undefined || Cast(dataField, listSpec(Doc), null)?.length !== undefined ? new List<Doc>([]) : undefined;
+            if (layoutKey !== "layout" && docView.rootDoc[layoutKey] instanceof Doc) {
+                newDoc[layoutKey] = docView.rootDoc[layoutKey];
+            }
+            Doc.GetProto(newDoc).text = undefined;
+            FormattedTextBox.SelectOnLoad = newDoc[Id];
+            return this.addDocument?.(newDoc);
+        }
+    }
     isContentActive = () => this.props.isSelected() || this.props.isContentActive();
     getDisplayDoc(doc: Doc, width: () => number) {
         const dataDoc = (!doc.isTemplateDoc && !doc.isTemplateForField && !doc.PARAMS) ? undefined : this.props.DataDoc;
@@ -225,6 +246,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
             docViewPath={this.props.docViewPath}
             fitWidth={this.props.childFitWidth}
             isContentActive={emptyFunction}
+            onKey={this.onKeyDown}
             isDocumentActive={this.isContentActive}
             LayoutTemplate={this.props.childLayoutTemplate}
             LayoutTemplateString={this.props.childLayoutString}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index dcff32d04..f4cb08f8f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1166,7 +1166,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     @action
     onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
         const docView = fieldProps.DocumentView?.();
-        if (docView && docView.rootDoc._singleLine && ["Tab", "Enter"].includes(e.key)) {
+        if (docView && (e.ctrlKey || e.shiftKey || e.altKey || docView.rootDoc._singleLine) && ["Tab", "Enter"].includes(e.key)) {
             e.stopPropagation?.();
             const below = !e.altKey && e.key !== "Tab";
             const layoutKey = StrCast(docView.LayoutFieldKey);
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 822bc996b..d468822c0 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -245,8 +245,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             const state = this._editorView.state.apply(tx);
             this._editorView.updateState(state);
 
-            const tsel = this._editorView.state.selection.$from;
-            //tsel.marks().filter(m => m.type === this._editorView!.state.schema.marks.user_mark).map(m => AudioBox.SetScrubTime(Math.max(0, m.attrs.modified * 1000)));
             const curText = state.doc.textBetween(0, state.doc.content.size, " \n");
             const curTemp = this.layoutDoc.resolvedDataDoc ? Cast(this.layoutDoc[this.props.fieldKey], RichTextField) : undefined;               // the actual text in the text box
             const curProto = Cast(Cast(this.dataDoc.proto, Doc, null)?.[this.fieldKey], RichTextField, null);              // the default text inherited from a prototype
@@ -348,7 +346,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     }
 
     autoLink = () => {
-        if (this._editorView) {
+        if (this._editorView?.state.doc.textContent) {
             const newAutoLinks = new Set<Doc>();
             const oldAutoLinks = DocListCast(this.props.Document.links).filter(link => link.linkRelationship === LinkManager.AutoKeywords);
             const f = this._editorView.state.selection.from;
@@ -962,7 +960,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             }, { fireImmediately: true }
         );
         quickScroll = undefined;
-        setTimeout(this.tryUpdateScrollHeight, 10);
+        this.tryUpdateScrollHeight();
     }
 
     pushToGoogleDoc = async () => {
@@ -1193,19 +1191,21 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
 
         const selectOnLoad = this.rootDoc[Id] === FormattedTextBox.SelectOnLoad && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath()));
         if (selectOnLoad && !this.props.dontRegisterView && !this.props.dontSelectOnLoad && this.isActiveTab(this.ProseRef)) {
+            const selLoadChar = FormattedTextBox.SelectOnLoadChar;
             FormattedTextBox.SelectOnLoad = "";
             this.props.select(false);
-            if (FormattedTextBox.SelectOnLoadChar && this._editorView) {
+            if (selLoadChar && this._editorView) {
                 const $from = this._editorView.state.selection.anchor ? this._editorView.state.doc.resolve(this._editorView.state.selection.anchor - 1) : undefined;
                 const mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) });
                 const curMarks = this._editorView.state.storedMarks ?? $from?.marksAcross(this._editorView.state.selection.$head) ?? [];
                 const storedMarks = [...curMarks.filter(m => m.type !== mark.type), mark];
                 const tr = this._editorView.state.tr.setStoredMarks(storedMarks).insertText(FormattedTextBox.SelectOnLoadChar, this._editorView.state.doc.content.size - 1, this._editorView.state.doc.content.size).setStoredMarks(storedMarks);
                 this._editorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(tr.doc.content.size))));
-                FormattedTextBox.SelectOnLoadChar = "";
-            } else if (curText && !FormattedTextBox.DontSelectInitialText) {
-                selectAll(this._editorView!.state, this._editorView?.dispatch);
+            } else if (this._editorView && curText && !FormattedTextBox.DontSelectInitialText) {
+                selectAll(this._editorView.state, this._editorView?.dispatch)
                 this.startUndoTypingBatch();
+            } else if (this._editorView) {
+                this._editorView.dispatch(this._editorView.state.tr.addStoredMark(schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) })));
             }
             FormattedTextBox.DontSelectInitialText = false;
         }
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
index 0dd0a8411..e979ae59e 100644
--- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
+++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
@@ -80,8 +80,10 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
     //Commands for lists
     bind("Ctrl-i", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && wrapInList(schema.nodes.ordered_list)(state as any, dispatch as any));
 
+    bind("Ctrl-Tab", () => props.onKey?.(event, props) ? true : true);
+    bind("Alt-Tab", () => props.onKey?.(event, props) ? true : true);
     bind("Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
-        if (props.onKey?.({ key: "Tab" }, props)) return true;
+        if (props.onKey?.(event, props)) return true;
         if (!canEdit(state)) return true;
         const ref = state.selection;
         const range = ref.$from.blockRange(ref.$to);
@@ -106,7 +108,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
     });
 
     bind("Shift-Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
-        if (props.onKey?.({ key: "Tab", shiftKey: true })) return true; // single line docs don't process tabs so that their containers can decide what to do.  This should be a prop
+        if (props.onKey?.(event, props)) return true;
         if (!canEdit(state)) return true;
         const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
 
@@ -154,11 +156,9 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
         return tx;
     };
 
-    //Command to create a text document to the right of the selected textbox
-    bind("Alt-Enter", () => true);
 
-    //Command to create a text document to the bottom of the selected textbox
-    bind("Ctrl-Enter", () => true);
+    bind("Alt-Enter", () => props.onKey?.(event, props) ? true : true);
+    bind("Ctrl-Enter", () => props.onKey?.(event, props) ? true : true);
 
     // backspace = chainCommands(deleteSelection, joinBackward, selectNodeBackward);
     bind("Backspace", (state: EditorState<S>, dispatch: (tx: Transaction<Schema<any, any>>) => void) => {
@@ -244,8 +244,6 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
         return false;
     });
 
-    // mac && bind("Ctrl-Enter", cmd);
-    // bind("Mod-Enter", cmd);
     bind("Shift-Enter", cmd);
 
     return keys;
diff --git a/src/fields/util.ts b/src/fields/util.ts
index c708affe3..ef5ac79b8 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -175,8 +175,11 @@ const getEffectiveAclCache = computedFn(function (target: any, user?: string) {
  * Calculates the effective access right to a document for the current user.
  */
 export function GetEffectiveAcl(target: any, user?: string): symbol {
-    return !target ? AclPrivate :
-        target[UpdatingFromServer] ? AclAdmin : getEffectiveAclCache(target, user);// all changes received from the server must be processed as Admin.  return this directly so that the acls aren't cached (UpdatingFromServer is not observable)
+    if (!target) return AclPrivate;
+    if (target[UpdatingFromServer]) return AclAdmin;
+    // authored documents are private until an ACL is set.  this also fixes notes that flicker on and off when a remote types to create a private note into a shared collection.
+    if (!target[AclSym] && target.author && target.author !== Doc.CurrentUserEmail) return AclPrivate;
+    return getEffectiveAclCache(target, user);// all changes received from the server must be processed as Admin.  return this directly so that the acls aren't cached (UpdatingFromServer is not observable)
 }
 
 function getPropAcl(target: any, prop: string | symbol | number) {
-- 
cgit v1.2.3-70-g09d2

