From 3573a81d334cf8cc13d19b04c6f2094c24c43932 Mon Sep 17 00:00:00 2001
From: Aubrey Li <Aubrey-Li>
Date: Thu, 3 Mar 2022 18:12:13 -0500
Subject: edit: lightbox opens tab in the same stack

---
 src/client/views/collections/CollectionDockingView.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index f543d924d..79e036a0e 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -449,7 +449,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
                     alert('cant delete the last stack');
                 }
             }));
-        stack.header?.controlsContainer.find('.lm_popout') //get the close icon
+        stack.header?.controlsContainer.find('.lm_popout') //get the popout icon
             .off('click') //unbind the current click handler
             .click(action(() => {
                 // stack.config.fixed = !stack.config.fixed;  // force the stack to have a fixed size
-- 
cgit v1.2.3-70-g09d2


From ef63a072a586f51e8fa51b4684987491287540b2 Mon Sep 17 00:00:00 2001
From: Naafiyan Ahmed <naafiyan@gmail.com>
Date: Thu, 7 Apr 2022 17:21:01 -0400
Subject: added grouping and write mode vs pen mode

---
 src/client/util/CurrentUserUtils.ts                |   4 +-
 src/client/views/GestureOverlay.tsx                |   5 +-
 .../views/collections/CollectionDockingView.tsx    |   2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  12 +--
 .../collections/collectionFreeForm/MarqueeView.tsx |   2 +-
 src/client/views/nodes/DocumentView.tsx            |   4 +-
 src/client/views/nodes/ImageBox.tsx                |   2 +-
 src/client/views/nodes/MapBox/MapBox.tsx           |   2 +-
 src/client/views/nodes/VideoBox.tsx                |   2 +-
 src/client/views/nodes/WebBox.tsx                  |   2 +-
 src/client/views/nodes/button/FontIconBox.tsx      | 112 ++++++++++-----------
 src/client/views/pdf/PDFViewer.tsx                 |   2 +-
 src/fields/InkField.ts                             |   3 +-
 webpack.config.js                                  |   2 +-
 14 files changed, 77 insertions(+), 79 deletions(-)

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

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 6cab8c100..f08f13bbc 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -1010,8 +1010,8 @@ export class CurrentUserUtils {
 
     static inkTools(doc: Doc) {
         const tools: Button[] = [
-            { title: "Pen", toolTip: "Pen (Ctrl+P)", btnType: ButtonType.ToggleButton, icon: "pen", click: 'setActiveInkTool("pen", _readOnly_)' },
-            { title: "Mode", toolTip: "Mode (Ctrl+P)", btnType: ButtonType.ToggleButton, icon: "pen", click: 'setActiveInkTool("write", _readOnly_)' },
+            { title: "Pen", toolTip: "Pen (Ctrl+P)", btnType: ButtonType.ToggleButton, icon: "pen-nib", click: 'setActiveInkTool("pen", _readOnly_)' },
+            { title: "Write", toolTip: "Write (Ctrl+Shift+P)", btnType: ButtonType.ToggleButton, icon: "pen", click: 'setActiveInkTool("write", _readOnly_)' },
             { title: "Eraser", toolTip: "Eraser (Ctrl+E)", btnType: ButtonType.ToggleButton, icon: "eraser", click: 'setActiveInkTool("eraser", _readOnly_)' },
             // { title: "Highlighter", toolTip: "Highlighter (Ctrl+H)", btnType: ButtonType.ToggleButton, icon: "highlighter", click: 'setActiveInkTool("highlighter")' },
             { title: "Circle", toolTip: "Circle (Ctrl+Shift+C)", btnType: ButtonType.ToggleButton, icon: "circle", click: 'setActiveInkTool("circle", _readOnly_)' },
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 87b006a93..53b360e60 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -491,7 +491,10 @@ export class GestureOverlay extends Touchable {
 
     @action
     onPointerDown = (e: React.PointerEvent) => {
-        if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || [InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
+        if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || [InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(CurrentUserUtils.SelectedTool)) {
+            if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) {
+                CurrentUserUtils.SelectedTool = InkTool.Write;
+            }
             this._points.push({ X: e.clientX, Y: e.clientY });
             setupMoveUpEvents(this, e, this.onPointerMove, this.onPointerUp, emptyFunction);
             // if (CurrentUserUtils.SelectedTool === InkTool.Highlighter) SetActiveInkColor("rgba(245, 230, 95, 0.75)");
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 9e8374605..c9f55a7bd 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -358,7 +358,7 @@ export class CollectionDockingView extends CollectionSubView() {
             }
         }
         if (!e.nativeEvent.cancelBubble && !InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE) && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE) &&
-            ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
+            ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(CurrentUserUtils.SelectedTool)) {
             e.stopPropagation();
         }
     }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index a694ca2b3..40164313c 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -468,6 +468,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                     case InkTool.Highlighter:
                         break;
                         // TODO: nda - this where we want to create the new "writingDoc" collection that we add strokes to
+                    case InkTool.Write:
+                        break;
                     case InkTool.Pen: 
                         // not the greatest solution
                         // want to have a currentInkDoc field
@@ -545,14 +547,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 const B = this.getTransform().transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
                 const inkDoc = Docs.Create.InkDocument(ActiveInkColor(), CurrentUserUtils.SelectedTool, ActiveInkWidth(), ActiveInkBezierApprox(), ActiveFillColor(), ActiveArrowStart(), ActiveArrowEnd(), ActiveDash(), points,
                     { title: "ink stroke", x: B.x - ActiveInkWidth() / 2, y: B.y - ActiveInkWidth() / 2, _width: B.width + ActiveInkWidth(), _height: B.height + ActiveInkWidth() });
-                // const currentInkDoc = Cast(this.dataDoc.currentInkDoc, Doc, null);
-                // if (true) {
                     console.log("doc exists")
-                    // Doc.AddDocToList(currentInkDoc.data as Doc, undefined, inkDoc)
-                    this.unprocessedDocs.push(inkDoc);
-                    CollectionFreeFormView.collectionsWithUnprocessedInk.add(this);
+                    if (CurrentUserUtils.SelectedTool === InkTool.Write) {
+                        this.unprocessedDocs.push(inkDoc);
+                        CollectionFreeFormView.collectionsWithUnprocessedInk.add(this);
+                    }
                     this.addDocument(inkDoc);
-                // } else this.addDocument(inkDoc);
                 e.stopPropagation();
                 break;
             case GestureUtils.Gestures.Box:
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index eeb2b653b..94f2d17de 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -651,7 +651,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
         return <div className="marqueeView"
             style={{
                 overflow: StrCast(this.props.Document._overflow),
-                cursor: CurrentUserUtils.SelectedTool === InkTool.Pen ? "crosshair" : "pointer"
+                cursor: CurrentUserUtils.SelectedTool === InkTool.Pen || InkTool.Write ? "crosshair" : "pointer"
             }}
 
             onDragOver={e => e.preventDefault()}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 7092b335c..2e822bb6a 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -517,7 +517,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
 
     onPointerDown = (e: React.PointerEvent): void => {
         // continue if the event hasn't been canceled AND we are using a mouse or this has an onClick or onDragStart function (meaning it is a button document)
-        if (!(InteractionUtils.IsType(e, InteractionUtils.MOUSETYPE) || [InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool))) {
+        if (!(InteractionUtils.IsType(e, InteractionUtils.MOUSETYPE) || [InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(CurrentUserUtils.SelectedTool))) {
             if (!InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) {
                 e.stopPropagation();
                 if (SelectionManager.IsSelected(this.props.DocumentView(), true) && this.props.Document._viewType !== CollectionViewType.Docking) e.preventDefault(); // goldenlayout needs to be able to move its tabs, so can't preventDefault for it
@@ -550,7 +550,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
 
     onPointerMove = (e: PointerEvent): void => {
         if (e.cancelBubble) return;
-        if ((InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || [InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool))) return;
+        if ((InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || [InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(CurrentUserUtils.SelectedTool))) return;
 
         if ((this.props.isDocumentActive?.() || this.layoutDoc.onDragStart) && !this.layoutDoc._lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) {
             if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) {
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 0a4168698..a8da22b61 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -322,7 +322,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
         return <div className="imageBox-annotationLayer" style={{ height: this.props.PanelHeight() }} ref={this._annotationLayer} />;
     }
     marqueeDown = (e: React.PointerEvent) => {
-        if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
+        if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(CurrentUserUtils.SelectedTool)) {
             setupMoveUpEvents(this, e, action(e => {
                 MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
                 this._marqueeing = [e.clientX, e.clientY];
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index aa2130af5..9bf7c2e8c 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -471,7 +471,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
 
     @action
     onMarqueeDown = (e: React.PointerEvent) => {
-        if (!e.altKey && e.button === 0 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
+        if (!e.altKey && e.button === 0 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(CurrentUserUtils.SelectedTool)) {
             setupMoveUpEvents(this, e, action(e => {
                 MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
                 this._marqueeing = [e.clientX, e.clientY];
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 33fdc4935..a5b8967c4 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -549,7 +549,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
     }
 
     marqueeDown = (e: React.PointerEvent) => {
-        if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
+        if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(CurrentUserUtils.SelectedTool)) {
             setupMoveUpEvents(this, e, action(e => {
                 MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
                 this._marqueeing = [e.clientX, e.clientY];
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 7ff47107e..54c49ecad 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -529,7 +529,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
 
     @action
     onMarqueeDown = (e: React.PointerEvent) => {
-        if (!e.altKey && e.button === 0 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
+        if (!e.altKey && e.button === 0 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(CurrentUserUtils.SelectedTool)) {
             setupMoveUpEvents(this, e, action(e => {
                 MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
                 this._marqueeing = [e.clientX, e.clientY];
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index fc0cc87ca..7f3a667a9 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -13,6 +13,7 @@ import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../../fields
 import { WebField } from '../../../../fields/URLField';
 import { aggregateBounds, Utils } from '../../../../Utils';
 import { DocumentType } from '../../../documents/DocumentTypes';
+import { CurrentUserUtils } from '../../../util/CurrentUserUtils';
 import { DocumentManager } from '../../../util/DocumentManager';
 import { ScriptingGlobals } from "../../../util/ScriptingGlobals";
 import { SelectionManager } from '../../../util/SelectionManager';
@@ -717,64 +718,56 @@ ScriptingGlobals.add(function setActiveInkTool(tool: string, checkResult?: boole
 
         // easy way without backing up to the server
         // 
-    CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => {
-        const selected = ffView.unprocessedDocs;
-        ffView._marqueeViewRef.current?.getCollection(ffView.unprocessedDocs, undefined, [], true);
-        // loop through selected an get the bound
-        const bounds: { x: number, y: number, width?: number, height?: number }[] = []
-        
-        selected.map(action(d => {
-            const x = NumCast(d.x);
-            const y = NumCast(d.y);
-            const width = d[WidthSym]();
-            const height = d[HeightSym]();
-            bounds.push({x, y, width, height});
-        }))
-
-        const aggregBounds = aggregateBounds(bounds, 0, 0);
-        const marqViewRef = ffView._marqueeViewRef.current;
-
-        // set the vals for bounds in marqueeView
-        if (marqViewRef) {
-            marqViewRef._downX = aggregBounds.x;
-            marqViewRef._downY = aggregBounds.y;
-            marqViewRef._lastX = aggregBounds.r;
-            marqViewRef._lastY = aggregBounds.b;
-        }        
-
-        selected.map(action(d => {
-            const dx = NumCast(d.x);
-            const dy = NumCast(d.y);
-            delete d.x;
-            delete d.y;
-            delete d.activeFrame;
-            delete d._timecodeToShow;  // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
-            delete d._timecodeToHide;  // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
-            // TODO: nda - actually calc the bounds
-            // get the bounds
-            // d.x = dx - aggregBounds.x;
-            // d.y = dy - aggregBounds.y;
+    if (CurrentUserUtils.SelectedTool === InkTool.Write) {
+        CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => {
+            const selected = ffView.unprocessedDocs;
+            // loop through selected an get the bound
+            const bounds: { x: number, y: number, width?: number, height?: number }[] = []
             
-            // d.x = dx - aggregBounds.x ;
-            // d.y = dy;
-            if (marqViewRef?.Bounds) {
-                d.x = dx - marqViewRef.Bounds.left - marqViewRef.Bounds?.width / 2;
-                d.y = dy - marqViewRef.Bounds.top - marqViewRef.Bounds.height / 2;
-            }
-            console.log(d[DataSym], d.x, d.y)
-            return d;
-        }));
-        ffView.props.removeDocument?.(selected);
-        // TODO: nda - this is the code to actually get a new grouped collection
-        // const newCollection = ffView._marqueeViewRef.current?.getCollection(ffView.unprocessedDocs, undefined, [], true);
-        const newCollection = marqViewRef?.getCollection(selected, undefined, [], true);
-        console.log("newcoll:", newCollection?.[DataSym]);
-
-        // nda - bug: when deleting a stroke before leaving writing mode, delete the stroke from unprocessed ink docs
-        newCollection && ffView.props.addDocument?.(newCollection);
-        ffView.unprocessedDocs = [];
-    });
-
+            selected.map(action(d => {
+                const x = NumCast(d.x);
+                const y = NumCast(d.y);
+                const width = d[WidthSym]();
+                const height = d[HeightSym]();
+                bounds.push({x, y, width, height});
+            }))
+    
+            const aggregBounds = aggregateBounds(bounds, 0, 0);
+            const marqViewRef = ffView._marqueeViewRef.current;
+    
+            // set the vals for bounds in marqueeView
+            if (marqViewRef) {
+                marqViewRef._downX = aggregBounds.x;
+                marqViewRef._downY = aggregBounds.y;
+                marqViewRef._lastX = aggregBounds.r;
+                marqViewRef._lastY = aggregBounds.b;
+            }        
+    
+            selected.map(action(d => {
+                const dx = NumCast(d.x);
+                const dy = NumCast(d.y);
+                delete d.x;
+                delete d.y;
+                delete d.activeFrame;
+                delete d._timecodeToShow;  // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
+                delete d._timecodeToHide;  // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection
+                // TODO: nda - actually calc the bounds
+                // calculate pos based on bounds
+                if (marqViewRef?.Bounds) {
+                    d.x = dx - marqViewRef.Bounds.left - marqViewRef.Bounds.width / 2;
+                    d.y = dy - marqViewRef.Bounds.top - marqViewRef.Bounds.height / 2;
+                }
+                return d;
+            }));
+            ffView.props.removeDocument?.(selected);
+            // TODO: nda - this is the code to actually get a new grouped collection
+            const newCollection = marqViewRef?.getCollection(selected, undefined, [], true);
+    
+            // nda - bug: when deleting a stroke before leaving writing mode, delete the stroke from unprocessed ink docs
+            newCollection && ffView.props.addDocument?.(newCollection);
+            ffView.unprocessedDocs = [];
+        });
+    }
     CollectionFreeFormView.collectionsWithUnprocessedInk.clear();
 
     if (checkResult) {
@@ -793,8 +786,9 @@ ScriptingGlobals.add(function setActiveInkTool(tool: string, checkResult?: boole
         if (Doc.UserDoc().activeInkTool === tool && !GestureOverlay.Instance.InkShape) {
             Doc.UserDoc().activeInkTool = InkTool.None;
         } else if (tool == "write") {
-            console.log("write mode selected - create groupDoc here!")
-            // 
+            console.log("write mode selected - create groupDoc here!", tool)
+            Doc.UserDoc().activeInkTool = tool;
+            GestureOverlay.Instance.InkShape = "";
         } else {
             Doc.UserDoc().activeInkTool = tool;
             GestureOverlay.Instance.InkShape = "";
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 1856c5353..37fbd7a1d 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -371,7 +371,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
         if ((e.button !== 0 || e.altKey) && this.props.isContentActive(true)) {
             this._setPreviewCursor?.(e.clientX, e.clientY, true, false);
         }
-        if (!e.altKey && e.button === 0 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
+        if (!e.altKey && e.button === 0 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(CurrentUserUtils.SelectedTool)) {
             this.props.select(false);
             MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
             this._marqueeing = [e.clientX, e.clientY];
diff --git a/src/fields/InkField.ts b/src/fields/InkField.ts
index 31024e805..c34e8f93d 100644
--- a/src/fields/InkField.ts
+++ b/src/fields/InkField.ts
@@ -11,7 +11,8 @@ export enum InkTool {
     Pen = "pen",
     Highlighter = "highlighter",
     Eraser = "eraser",
-    Stamp = "stamp"
+    Stamp = "stamp",
+    Write = "write"
 }
 
 
diff --git a/webpack.config.js b/webpack.config.js
index 3fd00bcf3..5a954db19 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -49,7 +49,7 @@ module.exports = {
         repl: ["./src/debug/Repl.tsx", 'webpack-hot-middleware/client?reload=true'],
         test: ["./src/debug/Test.tsx", 'webpack-hot-middleware/client?reload=true'],
         inkControls: ["./src/mobile/InkControls.tsx", 'webpack-hot-middleware/client?reload=true'],
-        mobileInterface: ["./src/mobile/MobileMain.tsx", 'webpack-hot-middleware/client?reload=true'],
+        mobileInterface: ["./src/client/views/Main.tsx", 'webpack-hot-middleware/client?reload=true'],
     },
     devtool: "source-map",
     output: {
-- 
cgit v1.2.3-70-g09d2


From 09c7ee4120f48e212f9b64fd3e307c8ce49e0cfd Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 16 May 2022 19:33:08 -0400
Subject: fixed snapshot to set 'context' of new aliases.

---
 src/client/views/collections/CollectionDockingView.tsx | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 64a5f38d4..30f60bba6 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -404,7 +404,10 @@ export class CollectionDockingView extends CollectionSubView() {
             const origtabdocs = DocListCast(origtab.data);
             const newtab = origtabdocs.length ? Doc.MakeCopy(origtab, true, undefined, true) : Doc.MakeAlias(origtab);
             const newtabdocs = origtabdocs.map(origtabdoc => Doc.MakeAlias(origtabdoc));
-            newtabdocs.length && (Doc.GetProto(newtab).data = new List<Doc>(newtabdocs));
+            if (newtabdocs.length) {
+                Doc.GetProto(newtab).data = new List<Doc>(newtabdocs);
+                newtabdocs.forEach(ntab => ntab.context = newtab);
+            }
             json = json.replace(origtab[Id], newtab[Id]);
             return newtab;
         });
-- 
cgit v1.2.3-70-g09d2


From d50b851d8e92797d214fc35cf243bfb29e970b36 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 23 May 2022 21:58:26 -0400
Subject: simplified dashboards by getting rid of confusing
 on-screen/off-screen tabs.  Now off screen tabs appear in the header bar
 which is not currently specific to a dashboard.

---
 src/client/documents/Documents.ts                  |  4 +-
 src/client/util/CurrentUserUtils.ts                | 33 +--------------
 src/client/views/MainView.tsx                      |  4 +-
 .../views/collections/CollectionDockingView.tsx    | 48 +++++++++++++++++-----
 src/client/views/collections/TabDocView.tsx        |  3 +-
 5 files changed, 43 insertions(+), 49 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 6fa467368..c3b6953b5 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -905,9 +905,7 @@ export namespace Docs {
         }
 
         export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) {
-            const tabs = TreeDocument(documents, { title: "On-Screen Tabs", childDontRegisterViews: true, freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", _fitWidth: true, system: true, isFolder: true });
-            const all = TreeDocument([], { title: "Off-Screen Tabs", childDontRegisterViews: true, freezeChildren: "add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", system: true, isFolder: true });
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id);
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { freezeChildren: "remove|add", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id);
         }
 
         export function DirectoryImportDocument(options: DocumentOptions = {}) {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 1e42b9073..9212d8ed9 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -1172,22 +1172,8 @@ export class CurrentUserUtils {
         freeformDoc.context = dashboardDoc;
 
         // switching the tabs from the datadoc to the regular doc
-        const dashboardTabs = dashboardDoc[DataSym].data;
-        dashboardDoc[DataSym].data = new List<Doc>();
-        dashboardDoc.data = dashboardTabs;
-
-        // collating all docs on the dashboard to make a data-all field
-        const allDocs = new List<Doc>();
-        const allDocs2 = new List<Doc>(); // Array.from, spread, splice all cause so stack or acl issues for some reason
-        DocListCast(dashboardTabs).forEach(doc => {
-            const tabDocs = DocListCast(doc.data);
-            allDocs.push(...tabDocs);
-            allDocs2.push(...tabDocs);
-        });
-        dashboardDoc[DataSym]["data-all"] = allDocs;
-        dashboardDoc["data-all"] = allDocs2;
-        DocListCast(dashboardDoc.data).forEach(doc => doc.dashboard = dashboardDoc);
-        DocListCast(dashboardDoc.data)[1].data = ComputedField.MakeFunction(`dynamicOffScreenDocs(self.dashboard)`) as any;
+        const dashboardTabs = DocListCast(dashboardDoc[DataSym].data);
+        dashboardDoc.data = new List<Doc>(dashboardTabs);
 
         userDoc.activePresentation = presentation;
 
@@ -1258,21 +1244,6 @@ ScriptingGlobals.add(function addToDashboards(dashboard: Doc) {
 },
     "adds Dashboard to set of Dashboards");
 
-/**
- * Dynamically computes which docs should be rendered in the off-screen tabs tree of a dashboard.
- */
-ScriptingGlobals.add(function dynamicOffScreenDocs(dashboard: Doc) {
-    if (dashboard[DataSym] instanceof Doc) {
-        const allDocs = DocListCast(dashboard["data-all"]);
-        const onScreenTab = DocListCast(dashboard.data)[0];
-        const onScreenDocs = DocListCast(onScreenTab.data);
-        return new List<Doc>(allDocs.reduce((result: Doc[], doc) => {
-            !onScreenDocs.includes(doc) && !onScreenDocs.includes(doc.aliasOf as Doc) && (result.push(doc));
-            return result;
-        }, []));
-    }
-    return [];
-});
 ScriptingGlobals.add(function selectedDocumentType(docType?: DocumentType, colType?: CollectionViewType, checkParent?: boolean) {
     let selected = SelectionManager.Docs().length ? SelectionManager.Docs()[0] : undefined;
     if (selected && checkParent) {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 69e394790..f3dc2cf85 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -92,7 +92,7 @@ export class MainView extends React.Component {
     @computed private get headerBarDoc() { return this.userDoc ? CurrentUserUtils.MyHeaderBarDoc : CurrentUserUtils.MyHeaderBarDoc; }
     @computed public get mainFreeform(): Opt<Doc> { return (docs => (docs?.length > 1) ? docs[1] : undefined)(DocListCast(this.mainContainer!.data)); }
 
-    headerBarDocWidth = () => this._dashUIWidth;
+    headerBarDocWidth = () => this.mainDocViewWidth();
     headerBarDocHeight = () => CurrentUserUtils.headerBarHeight ?? 0;
     topMenuHeight = () => 35;
     topMenuWidth = returnZero; // value is ignored ...
@@ -102,7 +102,7 @@ export class MainView extends React.Component {
     leftMenuFlyoutHeight = () => this._dashUIHeight;
     propertiesWidth = () => Math.max(0, Math.min(this._dashUIWidth - 50, CurrentUserUtils.propertiesWidth || 0));
     propertiesHeight = () => this._dashUIHeight;
-    mainDocViewWidth = () => this._dashUIWidth - this.propertiesWidth() - this.leftMenuWidth();
+    mainDocViewWidth = () => this._dashUIWidth - this.propertiesWidth() - this.leftMenuWidth() - this.leftMenuFlyoutWidth();
     mainDocViewHeight = () => this._dashUIHeight - this.headerBarDocHeight();
 
     componentDidMount() {
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 30f60bba6..1d65256a6 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -81,6 +81,8 @@ export class CollectionDockingView extends CollectionSubView() {
 
     tabItemDropped = () => DragManager.CompleteWindowDrag?.(false);
     tabDragStart = (proxy: any, finishDrag?: (aborted: boolean) => void) => {
+        const dashDoc = proxy?._contentItem?.tab?.DashDoc as Doc;
+        dashDoc && (DragManager.DocDragData = new DragManager.DocumentDragData([proxy._contentItem.tab.DashDoc]));
         DragManager.CompleteWindowDrag = (aborted: boolean) => {
             if (aborted) {
                 proxy._dragListener.AbortDrag();
@@ -90,6 +92,8 @@ export class CollectionDockingView extends CollectionSubView() {
                     this.setupGoldenLayout(); // restore golden layout to where it was before the drag (this is a no-op when using StartOtherDrag because the proxy dragged item was never in the golden layout)
                 }
                 DragManager.CompleteWindowDrag = undefined;
+            } else {
+                DragManager.DocDragData?.droppedDocuments.forEach(doc => this.addToTabDocList(doc));
             }
             finishDrag?.(aborted);
         };
@@ -100,12 +104,43 @@ export class CollectionDockingView extends CollectionSubView() {
         this.stateChanged();
     }
 
+    addToTabDocList = (document: Doc) => {
+        const instance = CollectionDockingView.Instance;
+        if (instance) {
+            const docList = DocListCast(instance.props.Document[DataSym].data);
+            // adds the doc of the newly created tab to the data-all field if it doesn't already include that doc or one of its aliases
+            !docList.includes(document) && !docList.includes(document.aliasOf as Doc) && Doc.AddDocToList(instance.props.Document[DataSym], "data", document);
+            // adds an alias of the doc to the data-all field of the layoutdocs of the aliases
+            DocListCast(instance.props.Document.aliases).forEach(alias => {
+                const aliasDocList = DocListCast(alias.data);
+                // if aliasDocList contains the alias, don't do anything
+                // otherwise add the original or an alias depending on whether the doc you're looking at is the current doc or a different alias
+                !DocListCast(document.aliases).some(a => aliasDocList.includes(a)) && Doc.AddDocToList(alias, "data", document);//alias !== instance.props.Document ? Doc.MakeAlias(document) : document);
+            });
+        }
+    }
+    removeFromTabDocList = (document: Doc) => {
+        const instance = CollectionDockingView.Instance;
+        if (instance) {
+            // adds the doc of the newly created tab to the data-all field if it doesn't already include that doc or one of its aliases
+            Doc.RemoveDocFromList(instance.props.Document[DataSym], "data", document);
+            // adds an alias of the doc to the data-all field of the layoutdocs of the aliases
+            DocListCast(instance.props.Document.aliases).forEach(alias => {
+                // if aliasDocList contains the alias, don't do anything
+                // otherwise add the original or an alias depending on whether the doc you're looking at is the current doc or a different alias
+                Doc.RemoveDocFromList(alias, "data", document);//alias !== instance.props.Document ? Doc.MakeAlias(document) : document);
+            });
+            document.type !== DocumentType.KVP && Doc.AddDocToList(CurrentUserUtils.MyHeaderBarDoc, "data", document);
+        }
+    }
+
     @undoBatch
     public static CloseSplit(document: Opt<Doc>, panelName?: string): boolean {
         const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find((tab) => panelName ? tab.contentItem.config.props.panelName === panelName : tab.DashDoc === document);
         if (tab) {
             const j = tab.header.parent.contentItems.indexOf(tab.contentItem);
             if (j !== -1) {
+                CollectionDockingView.Instance.removeFromTabDocList(tab.dashDoc as Doc);
                 tab.header.parent.contentItems[j].remove();
                 return CollectionDockingView.Instance.layoutChanged();
             }
@@ -185,16 +220,7 @@ export class CollectionDockingView extends CollectionSubView() {
         const instance = CollectionDockingView.Instance;
         if (!instance) return false;
         else {
-            const docList = DocListCast(instance.props.Document[DataSym]["data-all"]);
-            // adds the doc of the newly created tab to the data-all field if it doesn't already include that doc or one of its aliases
-            !docList.includes(document) && !docList.includes(document.aliasOf as Doc) && Doc.AddDocToList(instance.props.Document[DataSym], "data-all", document);
-            // adds an alias of the doc to the data-all field of the layoutdocs of the aliases
-            DocListCast(instance.props.Document[DataSym].aliases).forEach(alias => {
-                const aliasDocList = DocListCast(alias["data-all"]);
-                // if aliasDocList contains the alias, don't do anything
-                // otherwise add the original or an alias depending on whether the doc you're looking at is the current doc or a different alias
-                !DocListCast(document.aliases).some(a => aliasDocList.includes(a)) && Doc.AddDocToList(alias, "data-all", document);//alias !== instance.props.Document ? Doc.MakeAlias(document) : document);
-            });
+            instance.addToTabDocList(document);
         }
         const docContentConfig = CollectionDockingView.makeDocumentConfig(document, panelName);
 
@@ -477,7 +503,7 @@ export class CollectionDockingView extends CollectionSubView() {
                 //if (confirm('really close this?')) {
                 if (!stack.parent.parent.isRoot || stack.parent.contentItems.length > 1) {
                     stack.remove();
-                    stack.contentItems.forEach((contentItem: any) => Doc.AddDocToList(CurrentUserUtils.MyRecentlyClosed, "data", contentItem.tab.DashDoc, undefined, true, true));
+                    stack.contentItems.forEach((contentItem: any) => CollectionDockingView.Instance.removeFromTabDocList(contentItem.tab.DashDoc));
                 } else {
                     alert('cant delete the last stack');
                 }
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 0070d0b9d..88d14fdfe 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -180,8 +180,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
             tab.closeElement.off('click') //unbind the current click handler
                 .click(function () {
                     Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
-                    Doc.AddDocToList(CurrentUserUtils.MyHeaderBarDoc, "data", doc);
-                    Doc.AddDocToList(CurrentUserUtils.MyRecentlyClosed, "data", doc, undefined, true, true);
+                    CollectionDockingView.Instance?.removeFromTabDocList(doc);
                     SelectionManager.DeselectAll();
                     UndoManager.RunInBatch(() => tab.contentItem.remove(), "delete tab");
                 });
-- 
cgit v1.2.3-70-g09d2


From 76d737a05093e4132f2ab56630c4003879747ef9 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 26 May 2022 15:36:32 -0400
Subject: removed setting 'data' field of docking views on aliases.    assigned
 acl's to delegates to match prototype.  changed how documents are created to
 make sure acl's are set first so that, when sharing, remote clients will get
 the ACLs first and not render documents transiently when they don't have
 permissions.  turned off inheriting ACL's from outer collection

---
 src/client/documents/Documents.ts                      | 15 +++++++++------
 src/client/util/CurrentUserUtils.ts                    |  3 ---
 src/client/views/collections/CollectionDockingView.tsx | 17 ++---------------
 src/client/views/global/globalCssVariables.scss        |  2 +-
 src/fields/Doc.ts                                      |  1 +
 src/fields/util.ts                                     |  3 ++-
 6 files changed, 15 insertions(+), 26 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index ed37c48dc..8d29bcebe 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -639,13 +639,14 @@ export namespace Docs {
             const viewKeys = ["x", "y", "system"]; // keys that should be addded to the view document even though they don't begin with an "_"
             const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, "^_");
 
+            dataProps["acl-Override"] = "None";
+            dataProps["acl-Public"] = options["acl-Public"] ? options["acl-Public"] : Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment;
+
             dataProps.system = viewProps.system;
             dataProps.isPrototype = true;
             dataProps.author = Doc.CurrentUserEmail;
             dataProps.creationDate = new DateField;
             dataProps[`${fieldKey}-lastModified`] = new DateField;
-            dataProps["acl-Override"] = "None";
-            dataProps["acl-Public"] = options["acl-Public"] ? options["acl-Public"] : Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment;
 
             dataProps[fieldKey] = data;
 
@@ -654,10 +655,12 @@ export namespace Docs {
             dataProps[fieldKey + "-annotations"] = new List<Doc>();
             const dataDoc = Doc.assign(Doc.MakeDelegate(proto, protoId), dataProps, undefined, true);
 
-            viewProps.author = Doc.CurrentUserEmail;
-            viewProps["acl-Override"] = "None";
-            viewProps["acl-Public"] = options["_acl-Public"] ? options["_acl-Public"] : Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment;
-            const viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewProps, true, true);
+            const viewFirstProps: { [id: string]: any } = {};
+            viewFirstProps["acl-Public"] = options["_acl-Public"] ? options["_acl-Public"] : Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment;
+            viewFirstProps["acl-Override"] = "None";
+            viewFirstProps.author = Doc.CurrentUserEmail;
+            const viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewFirstProps, true, true);
+            Doc.assign(viewDoc, viewProps, true, true);
             ![DocumentType.LINK, DocumentType.MARKER, DocumentType.LABEL].includes(viewDoc.type as any) && DocUtils.MakeLinkToActiveAudio(() => viewDoc);
 
             !Doc.IsSystem(dataDoc) && ![DocumentType.MARKER, DocumentType.KVP, DocumentType.LINK, DocumentType.LINKANCHOR].includes(proto.type as any) &&
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 436237d6c..083530ce7 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -1236,9 +1236,6 @@ ScriptingGlobals.add(async function removeDashboard(dashboard: Doc) {
     "Remove Dashboard from Dashboards");
 ScriptingGlobals.add(function addToDashboards(dashboard: Doc) {
     const dashboardAlias = Doc.MakeAlias(dashboard);
-    dashboardAlias.data = new List<Doc>(DocListCast(dashboard.data).map(tabFolder => Doc.MakeAlias(tabFolder)));
-    DocListCast(dashboardAlias.data).forEach(doc => doc.dashboard = dashboardAlias);
-    DocListCast(dashboardAlias.data)[1].data = ComputedField.MakeFunction(`dynamicOffScreenDocs(self.dashboard)`) as any;
     Doc.AddDocToList(CurrentUserUtils.MyDashboards, "data", dashboardAlias);
     CurrentUserUtils.openDashboard(Doc.UserDoc(), dashboardAlias);
 },
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 1d65256a6..c60434d95 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -109,27 +109,14 @@ export class CollectionDockingView extends CollectionSubView() {
         if (instance) {
             const docList = DocListCast(instance.props.Document[DataSym].data);
             // adds the doc of the newly created tab to the data-all field if it doesn't already include that doc or one of its aliases
-            !docList.includes(document) && !docList.includes(document.aliasOf as Doc) && Doc.AddDocToList(instance.props.Document[DataSym], "data", document);
-            // adds an alias of the doc to the data-all field of the layoutdocs of the aliases
-            DocListCast(instance.props.Document.aliases).forEach(alias => {
-                const aliasDocList = DocListCast(alias.data);
-                // if aliasDocList contains the alias, don't do anything
-                // otherwise add the original or an alias depending on whether the doc you're looking at is the current doc or a different alias
-                !DocListCast(document.aliases).some(a => aliasDocList.includes(a)) && Doc.AddDocToList(alias, "data", document);//alias !== instance.props.Document ? Doc.MakeAlias(document) : document);
-            });
+            !docList.includes(document) && !docList.includes(document.aliasOf as Doc) && Doc.AddDocToList(instance.props.Document, "data", document);
         }
     }
     removeFromTabDocList = (document: Doc) => {
         const instance = CollectionDockingView.Instance;
         if (instance) {
             // adds the doc of the newly created tab to the data-all field if it doesn't already include that doc or one of its aliases
-            Doc.RemoveDocFromList(instance.props.Document[DataSym], "data", document);
-            // adds an alias of the doc to the data-all field of the layoutdocs of the aliases
-            DocListCast(instance.props.Document.aliases).forEach(alias => {
-                // if aliasDocList contains the alias, don't do anything
-                // otherwise add the original or an alias depending on whether the doc you're looking at is the current doc or a different alias
-                Doc.RemoveDocFromList(alias, "data", document);//alias !== instance.props.Document ? Doc.MakeAlias(document) : document);
-            });
+            Doc.RemoveDocFromList(instance.props.Document, "data", document);
             document.type !== DocumentType.KVP && Doc.AddDocToList(CurrentUserUtils.MyHeaderBarDoc, "data", document);
         }
     }
diff --git a/src/client/views/global/globalCssVariables.scss b/src/client/views/global/globalCssVariables.scss
index 520ac9357..a14634bdc 100644
--- a/src/client/views/global/globalCssVariables.scss
+++ b/src/client/views/global/globalCssVariables.scss
@@ -10,7 +10,7 @@ $black: #000000;
 $light-blue: #bdddf5;
 $light-blue-transparent: #bdddf590;
 $medium-blue: #4476f7;
-$medium-blue-alt: #4476f73d;
+$medium-blue-alt: #0047ff54;
 $pink: #e0217d;
 $yellow: #f5d747;
 
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 194b3ba27..b0a45091e 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -821,6 +821,7 @@ export namespace Doc {
             delegate[Initializing] = true;
             delegate.proto = doc;
             delegate.author = Doc.CurrentUserEmail;
+            Object.keys(doc).filter(key => key.startsWith("acl")).forEach(key => delegate[key] = doc[key]);
             if (!Doc.IsSystem(doc)) Doc.AddDocToList(doc[DataSym], "aliases", delegate);
             title && (delegate.title = title);
             delegate[Initializing] = false;
diff --git a/src/fields/util.ts b/src/fields/util.ts
index ef5ac79b8..d1e565774 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -138,6 +138,7 @@ export function denormalizeEmail(email: string) {
  * Copies parent's acl fields to the child
  */
 export function inheritParentAcls(parent: Doc, child: Doc) {
+    return;
     const dataDoc = parent[DataSym];
     for (const key of Object.keys(dataDoc)) {
         // if the default acl mode is private, then don't inherit the acl-Public permission, but set it to private.
@@ -177,7 +178,7 @@ const getEffectiveAclCache = computedFn(function (target: any, user?: string) {
 export function GetEffectiveAcl(target: any, user?: string): symbol {
     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.
+    // authored documents are private until an ACL is set.
     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)
 }
-- 
cgit v1.2.3-70-g09d2


From ddd38f923180efd0dc4f53a1c3caad4a1f9ed26f Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 26 May 2022 17:40:54 -0400
Subject: removed more code relating to old version of dashboards with on and
 off screen tab lists.  fixed schema headers to not iconify when typing Enter
 in header field name.

---
 .../views/collections/CollectionDockingView.tsx    | 47 +---------------------
 src/client/views/collections/TabDocView.tsx        |  1 -
 .../collectionSchema/CollectionSchemaHeaders.tsx   |  5 ++-
 3 files changed, 6 insertions(+), 47 deletions(-)

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

diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index c60434d95..509da18cb 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -92,8 +92,6 @@ export class CollectionDockingView extends CollectionSubView() {
                     this.setupGoldenLayout(); // restore golden layout to where it was before the drag (this is a no-op when using StartOtherDrag because the proxy dragged item was never in the golden layout)
                 }
                 DragManager.CompleteWindowDrag = undefined;
-            } else {
-                DragManager.DocDragData?.droppedDocuments.forEach(doc => this.addToTabDocList(doc));
             }
             finishDrag?.(aborted);
         };
@@ -104,30 +102,12 @@ export class CollectionDockingView extends CollectionSubView() {
         this.stateChanged();
     }
 
-    addToTabDocList = (document: Doc) => {
-        const instance = CollectionDockingView.Instance;
-        if (instance) {
-            const docList = DocListCast(instance.props.Document[DataSym].data);
-            // adds the doc of the newly created tab to the data-all field if it doesn't already include that doc or one of its aliases
-            !docList.includes(document) && !docList.includes(document.aliasOf as Doc) && Doc.AddDocToList(instance.props.Document, "data", document);
-        }
-    }
-    removeFromTabDocList = (document: Doc) => {
-        const instance = CollectionDockingView.Instance;
-        if (instance) {
-            // adds the doc of the newly created tab to the data-all field if it doesn't already include that doc or one of its aliases
-            Doc.RemoveDocFromList(instance.props.Document, "data", document);
-            document.type !== DocumentType.KVP && Doc.AddDocToList(CurrentUserUtils.MyHeaderBarDoc, "data", document);
-        }
-    }
-
     @undoBatch
     public static CloseSplit(document: Opt<Doc>, panelName?: string): boolean {
         const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find((tab) => panelName ? tab.contentItem.config.props.panelName === panelName : tab.DashDoc === document);
         if (tab) {
             const j = tab.header.parent.contentItems.indexOf(tab.contentItem);
             if (j !== -1) {
-                CollectionDockingView.Instance.removeFromTabDocList(tab.dashDoc as Doc);
                 tab.header.parent.contentItems[j].remove();
                 return CollectionDockingView.Instance.layoutChanged();
             }
@@ -206,9 +186,6 @@ export class CollectionDockingView extends CollectionSubView() {
         }
         const instance = CollectionDockingView.Instance;
         if (!instance) return false;
-        else {
-            instance.addToTabDocList(document);
-        }
         const docContentConfig = CollectionDockingView.makeDocumentConfig(document, panelName);
 
         if (!pullSide && stack) {
@@ -434,29 +411,10 @@ export class CollectionDockingView extends CollectionSubView() {
         const matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g);
         const docids = matches?.map(m => m.replace("\"documentId\":\"", "").replace("\"", ""));
         const docs = !docids ? [] : docids.map(id => DocServer.GetCachedRefField(id)).filter(f => f).map(f => f as Doc);
-        const changesMade = this.props.Document.dockingConfig !== json;
+        const changesMade = this.props.Document.dockcingConfig !== json;
         if (changesMade && !this._flush) {
             this.props.Document.dockingConfig = json;
-            setTimeout(async () => {
-                const sublists = await DocListCastAsync(this.props.Document[this.props.fieldKey]);
-                const tabs = sublists && Cast(sublists[0], Doc, null);
-                // const other = sublists && Cast(sublists[1], Doc, null);
-                const tabdocs = await DocListCastAsync(tabs?.data);
-                // const otherdocs = await DocListCastAsync(other?.data);
-                if (tabs) {
-                    tabs.data = new List<Doc>(docs);
-                    // DocListCast(tabs.aliases).forEach(tab => tab !== tabs && (tab.data = new List<Doc>(docs)));
-                }
-                // const otherSet = new Set<Doc>();
-                // otherdocs?.filter(doc => !docs.includes(doc)).forEach(doc => otherSet.add(doc));
-                // tabdocs?.filter(doc => !docs.includes(doc) && doc.type !== DocumentType.KVP).forEach(doc => otherSet.add(doc));
-                // const vals = Array.from(otherSet.values()).filter(val => val instanceof Doc).map(d => d).filter(d => d.type !== DocumentType.KVP);
-                // this.props.Document[DataSym][this.props.fieldKey + "-all"] = new List<Doc>([...docs, ...vals]);
-                // if (other) {
-                //     other.data = new List<Doc>(vals);
-                //     // DocListCast(other.aliases).forEach(tab => tab !== other && (tab.data = new List<Doc>(vals)));
-                // }
-            }, 0);
+            this.props.Document.data = new List<Doc>(docs);
         }
         return changesMade;
     }
@@ -490,7 +448,6 @@ export class CollectionDockingView extends CollectionSubView() {
                 //if (confirm('really close this?')) {
                 if (!stack.parent.parent.isRoot || stack.parent.contentItems.length > 1) {
                     stack.remove();
-                    stack.contentItems.forEach((contentItem: any) => CollectionDockingView.Instance.removeFromTabDocList(contentItem.tab.DashDoc));
                 } else {
                     alert('cant delete the last stack');
                 }
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index a2ba504dc..2b78b20ea 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -180,7 +180,6 @@ export class TabDocView extends React.Component<TabDocViewProps> {
             tab.closeElement.off('click') //unbind the current click handler
                 .click(function () {
                     Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
-                    CollectionDockingView.Instance?.removeFromTabDocList(doc);
                     SelectionManager.DeselectAll();
                     UndoManager.RunInBatch(() => tab.contentItem.remove(), "delete tab");
                 });
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
index dc35b5749..0875c80b3 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx
@@ -278,6 +278,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
     @undoBatch
     onKeyDown = (e: React.KeyboardEvent): void => {
         if (e.key === "Enter") {
+            e.stopPropagation();
             if (this._searchTerm.includes(":")) {
                 const colpos = this._searchTerm.indexOf(":");
                 const temp = this._searchTerm.slice(colpos + 1, this._searchTerm.length);
@@ -490,7 +491,9 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
 
                 <div className="keys-dropdown" style={{ zIndex: 1, width: this.props.width, maxWidth: this.props.width }}>
                     <input className="keys-search" style={{ width: "100%" }}
-                        ref={this._inputRef} type="text" value={this._searchTerm} placeholder="Column key" onKeyDown={this.onKeyDown}
+                        ref={this._inputRef} type="text"
+                        value={this._searchTerm} placeholder="Column key"
+                        onKeyDown={this.onKeyDown}
                         onChange={e => this.onChange(e.target.value)}
                         onClick={(e) => { e.stopPropagation(); this._inputRef.current?.focus(); }}
                         onFocus={this.onFocus} ></input>
-- 
cgit v1.2.3-70-g09d2


From b0408fa264fc8a017c87a17325600d8e458fe711 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 6 Jun 2022 01:32:36 -0400
Subject: fixed up overlayDocs a bit so that they can be removed.  made
 audioBox's appear in overlay when clicked from toolbar. add links to audio
 when navigating to doc in lightbox.

---
 src/client/util/CurrentUserUtils.ts                    |  4 ++--
 src/client/views/LightboxView.tsx                      |  2 ++
 src/client/views/OverlayView.tsx                       | 10 +++++++---
 src/client/views/collections/CollectionDockingView.tsx |  2 ++
 src/client/views/nodes/AudioBox.tsx                    |  9 ++++++++-
 5 files changed, 21 insertions(+), 6 deletions(-)

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

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index cad86c0a6..51bfdbbd2 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -276,7 +276,7 @@ export class CurrentUserUtils {
             (doc.emptyWall as Doc).videoWall = true;
         }
         if (doc.emptyAudio === undefined) {
-            doc.emptyAudio = Docs.Create.AudioDocument(nullAudio, { ...standardOps(), title: "audio recording", _width: 200, _height: 100, });
+            doc.emptyAudio = Docs.Create.AudioDocument(nullAudio, { ...standardOps(), title: "audio recording", x: 200, y: 200, _width: 200, _height: 100, });
         }
         if (doc.emptyNote === undefined) {
             doc.emptyNote = Docs.Create.TextDocument("", { ...standardOps(), title: "text note", _width: 200, _autoHeight: true });
@@ -301,7 +301,7 @@ export class CurrentUserUtils {
             { toolTip: "Tap to create a comparison box in a new pane, drag for a comparison box", title: "Compare", icon: "columns", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyComparison as Doc, noviceMode: true },
             { toolTip: "Tap to create a screen grabber in a new pane, drag for a screen grabber", title: "Grab", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScreenshot as Doc },
             { toolTip: "Tap to create a videoWall", title: "Wall", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyWall as Doc },
-            { toolTip: "Tap to create an audio recorder in a new pane, drag for an audio recorder", title: "Audio", icon: "microphone", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyAudio as Doc, noviceMode: true },
+            { toolTip: "Tap to create an audio recorder in a overlay pane, drag for an audio recorder", title: "Audio", icon: "microphone", click: 'openInOverlay(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyAudio as Doc, noviceMode: true },
             { toolTip: "Tap to create a button in a new pane, drag for a button", title: "Button", icon: "bolt", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyButton as Doc },
             // { toolTip: "Tap to create a presentation in a new pane, drag for a presentation", title: "Trails", icon: "pres-trail", click: 'openOnRight(Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory))', drag: `Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory)`, dragFactory: doc.emptyPresentation as Doc, noviceMode: true },
             { toolTip: "Tap to create a scripting box in a new pane, drag for a scripting box", title: "Script", icon: "terminal", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScript as Doc },
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 2543111b0..f67f37bfb 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -126,6 +126,8 @@ export class LightboxView extends React.Component<LightboxViewProps> {
         const target = LightboxView._docTarget = this._future?.pop();
         const targetDocView = target && DocumentManager.Instance.getLightboxDocumentView(target);
         if (targetDocView && target) {
+            const l = DocUtils.MakeLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.() || target).lastElement();
+            l && (Cast(l.anchor2, Doc, null).backgroundColor = "lightgreen");
             targetDocView.focus(target, { originalTarget: target, willZoom: true, scale: 0.9 });
             if (LightboxView._history?.lastElement().target !== target) LightboxView._history?.push({ doc, target });
         } else {
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index 18b87e3d5..95e146df4 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -146,6 +146,10 @@ export class OverlayView extends React.Component {
         return remove;
     }
 
+    removeOverlayDoc = (doc: Doc | Doc[]) => {
+        (doc instanceof Doc ? [doc] : doc).forEach(doc => Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc));
+        return true;
+    }
 
     @computed get overlayDocs() {
         return CurrentUserUtils.OverlayDocs?.map(d => {
@@ -179,16 +183,16 @@ export class OverlayView extends React.Component {
                 offsetx = NumCast(d.x) - e.clientX;
                 offsety = NumCast(d.y) - e.clientY;
             };
-            return <div className="overlayView-doc" ref={dref} key={d[Id]} onPointerDown={onPointerDown} style={{ top: d.type === 'presentation' ? 0 : undefined, width: NumCast(d._width), height: NumCast(d._height), transform: `translate(${d.x}px, ${d.y}px)` }}>
+            return <div className="overlayView-doc" ref={dref} key={d[Id]} onPointerDown={onPointerDown} style={{ top: 0, width: NumCast(d._width), height: NumCast(d._height), transform: `translate(${d.x}px, ${d.y}px)` }}>
                 <DocumentView
                     Document={d}
                     rootSelected={returnTrue}
                     bringToFront={emptyFunction}
                     addDocument={undefined}
-                    removeDocument={undefined}
+                    removeDocument={this.removeOverlayDoc}
                     PanelWidth={d[WidthSym]}
                     PanelHeight={d[HeightSym]}
-                    ScreenToLocalTransform={Transform.Identity}
+                    ScreenToLocalTransform={() => new Transform(-NumCast(d.x), -NumCast(d.y), 1)}
                     renderDepth={1}
                     isDocumentActive={returnFalse}
                     isContentActive={returnTrue}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 5c0d6b1c4..de2106e4a 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -475,4 +475,6 @@ ScriptingGlobals.add(function openInLightbox(doc: any) { LightboxView.AddDocTab(
     "opens up document in a lightbox", "(doc: any)");
 ScriptingGlobals.add(function openOnRight(doc: any) { return CollectionDockingView.AddSplit(doc, "right"); },
     "opens up document in tab on right side of the screen", "(doc: any)");
+ScriptingGlobals.add(function openInOverlay(doc: any) { return Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc); },
+    "opens up document in screen overlay layer", "(doc: any)");
 ScriptingGlobals.add(function useRightSplit(doc: any, shiftKey?: boolean) { CollectionDockingView.ReplaceTab(doc, "right", undefined, shiftKey); });
\ No newline at end of file
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 9b92762a2..787ad939d 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -350,7 +350,14 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
         Doc.GetProto(newDoc).recordingSource = this.dataDoc;
         Doc.GetProto(newDoc).recordingStart = ComputedField.MakeFunction(`self.recordingSource["${this.fieldKey}-recordingStart"]`);
         Doc.GetProto(newDoc).mediaState = ComputedField.MakeFunction("self.recordingSource.mediaState");
-        this.props.addDocument?.(newDoc);
+        const overlayDoc = Doc.UserDoc().myOverlayDocs as Doc;
+        if (DocListCast(overlayDoc[Doc.LayoutFieldKey(overlayDoc)]).includes(this.rootDoc)) {
+            newDoc.x = this.rootDoc.x;
+            newDoc.y = NumCast(this.rootDoc.y) + NumCast(this.rootDoc._height);
+            Doc.AddDocToList(overlayDoc, undefined, newDoc);
+        } else {
+            this.props.addDocument?.(newDoc);
+        }
         e.stopPropagation();
     }
 
-- 
cgit v1.2.3-70-g09d2

