From a14e2da6130ac3c0c55b03cbc8a5fa3723be45bc Mon Sep 17 00:00:00 2001
From: Geireann <60007097+geireann@users.noreply.github.com>
Date: Tue, 6 Apr 2021 20:31:25 -0400
Subject: updates

---
 src/client/views/collections/CollectionMenu.tsx | 78 ++++++++++++++++++-------
 1 file changed, 58 insertions(+), 20 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 623e05b33..3321a8d8f 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -15,7 +15,7 @@ import { RichTextField } from "../../../fields/RichTextField";
 import { listSpec } from "../../../fields/Schema";
 import { ScriptField } from "../../../fields/ScriptField";
 import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
-import { emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils";
+import { DeepCopy, emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils";
 import { DocumentType } from "../../documents/DocumentTypes";
 import { CurrentUserUtils } from "../../util/CurrentUserUtils";
 import { DragManager } from "../../util/DragManager";
@@ -34,6 +34,9 @@ import "./CollectionMenu.scss";
 import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView";
 import { TabDocView } from "./TabDocView";
 import { LightboxView } from "../LightboxView";
+import { Docs } from "../../documents/Documents";
+import { DocumentManager } from "../../util/DocumentManager";
+import { CollectionDockingView } from "./CollectionDockingView";
 
 @observer
 export class CollectionMenu extends AntimodeMenu<AntimodeMenuProps> {
@@ -388,7 +391,32 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
         return !targetDoc ? (null) : <Tooltip key="pin" title={<div className="dash-tooltip">{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}</div>} placement="top">
             <button className="antimodeMenu-button" style={{ backgroundColor: isPinned ? "121212" : undefined, borderLeft: "1px solid gray" }}
                 onClick={e => TabDocView.PinDoc(targetDoc, { unpin: isPinned })}>
-                <FontAwesomeIcon className="documentdecorations-icon" size="lg" icon="map-pin" />
+                <FontAwesomeIcon className="colMenu-icon" size="lg" icon="map-pin" />
+            </button>
+        </Tooltip>;
+    }
+
+    @undoBatch
+    @action
+    startRecording = () => {
+        const doc = Docs.Create.ScreenshotDocument("", { _fitWidth: true, _width: 400, _height: 200, title: "screen snapshot", system: true, cloneFieldFilter: new List<string>(["system"]) });
+        doc.x = 0;
+        doc.y = 0;
+        Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc);
+        CollectionDockingView.AddSplit(doc, "right");
+        // doc.startRec = true;
+    }
+
+    @computed
+    get recordButton() {
+        const targetDoc = this.selectedDoc;
+        return <Tooltip key="record" title={<div className="dash-tooltip">{"Capture screen"}</div>} placement="top">
+            <button className="antimodeMenu-button"
+                onClick={e => this.startRecording()}>
+                <div className="recordButtonOutline" style={{}}>
+                    <div className="recordButtonInner" style={{}}>
+                    </div>
+                </div>
             </button>
         </Tooltip>;
     }
@@ -478,7 +506,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
         const targetDoc = this.selectedDoc;
         return !targetDoc || targetDoc.type === DocumentType.PRES ? (null) : <Tooltip title={<div className="dash-tooltip">{"Tap or Drag to create an alias"}</div>} placement="top">
             <button className="antimodeMenu-button" onPointerDown={this.onAliasButtonDown} onClick={this.onAlias} style={{ cursor: "drag" }}>
-                <FontAwesomeIcon className="documentdecorations-icon" icon="copy" size="lg" />
+                <FontAwesomeIcon className="colMenu-icon" icon="copy" size="lg" />
             </button>
         </Tooltip>;
     }
@@ -486,38 +514,48 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
     @computed get lightboxButton() {
         const targetDoc = this.selectedDoc;
         return !targetDoc ? (null) : <Tooltip title={<div className="dash-tooltip">{"View in Lightbox"}</div>} placement="top">
-            <button className="antimodeMenu-button" style={{ borderRight: "1px solid gray", justifyContent: 'center' }} onPointerDown={() => {
+            <button className="antimodeMenu-button" onPointerDown={() => {
                 const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
                 LightboxView.SetLightboxDoc(targetDoc, undefined, docs);
             }}>
-                <FontAwesomeIcon className="documentdecorations-icon" icon="desktop" size="lg" />
+                <FontAwesomeIcon className="colMenu-icon" icon="desktop" size="lg" />
             </button>
         </Tooltip>;
     }
 
+    @computed get toggleOverlayButton() {
+        return <>
+            <Tooltip title={<div className="dash-tooltip">Toggle Overlay Layer</div>} placement="bottom">
+                <button className={"antimodeMenu-button"} key="float"
+                    style={{
+                        backgroundColor: this.props.docView.layoutDoc.z ? "121212" : undefined,
+                        pointerEvents: this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? "none" : undefined,
+                        color: this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? "dimgrey" : undefined
+                    }}
+                    onClick={undoBatch(() => this.props.docView.props.CollectionFreeFormDocumentView?.().float())}>
+                    <FontAwesomeIcon icon={["fab", "buffer"]} size={"lg"} />
+                </button>
+            </Tooltip>
+        </>
+    }
+
     render() {
         return (
             <div className="collectionMenu-cont" >
                 <div className="collectionMenu">
                     <div className="collectionViewBaseChrome">
+                        {this.notACollection || this.props.type === CollectionViewType.Invalid ? (null) : this.viewModes}
+                        <div className="collectionMenu-divider" key="divider1"></div>
                         {this.aliasButton}
                         {/* {this.pinButton} */}
-                        {this.pinWithViewButton}
-                        {this.lightboxButton}
-                        <Tooltip title={<div className="dash-tooltip">Toggle Overlay Layer</div>} placement="bottom">
-                            <button className={"antimodeMenu-button"} key="float"
-                                style={{
-                                    backgroundColor: this.props.docView.layoutDoc.z ? "121212" : undefined, borderRight: "1px solid gray",
-                                    pointerEvents: this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? "none" : undefined,
-                                    color: this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? "dimgrey" : undefined
-                                }}
-                                onClick={undoBatch(() => this.props.docView.props.CollectionFreeFormDocumentView?.().float())}>
-                                <FontAwesomeIcon icon={["fab", "buffer"]} size={"lg"} />
-                            </button>
-                        </Tooltip>
+                        {/* {this.pinWithViewButton} */}
+                        {this.toggleOverlayButton}
+                        <div className="collectionMenu-divider" key="divider2"></div>
                         {this.subChrome}
-                        {this.notACollection || this.props.type === CollectionViewType.Invalid ? (null) : this.viewModes}
-                        {!this._buttonizableCommands ? (null) : this.templateChrome}
+                        <div className="collectionMenu-divider" key="divider3"></div>
+                        {this.lightboxButton}
+                        {this.recordButton}
+                        {/* {!this._buttonizableCommands ? (null) : this.templateChrome} */}
                     </div>
                 </div>
             </div>
-- 
cgit v1.2.3-70-g09d2


From 6a73699a10edb842b2b5eba4ef05731772859f13 Mon Sep 17 00:00:00 2001
From: Geireann <60007097+geireann@users.noreply.github.com>
Date: Wed, 7 Apr 2021 14:45:14 -0400
Subject: bug fixes

---
 src/client/util/CaptureManager.scss                | 450 ++-------------------
 src/client/util/CaptureManager.tsx                 |  47 ++-
 src/client/views/LightboxView.tsx                  |   7 +-
 src/client/views/MainViewModal.tsx                 |   2 +-
 src/client/views/collections/CollectionMenu.tsx    |   2 +-
 src/client/views/nodes/ScreenshotBox.tsx           | 150 +++----
 .../views/presentationview/PresElementBox.tsx      |   2 +
 7 files changed, 160 insertions(+), 500 deletions(-)

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

diff --git a/src/client/util/CaptureManager.scss b/src/client/util/CaptureManager.scss
index 5ca54517c..8447bd2d5 100644
--- a/src/client/util/CaptureManager.scss
+++ b/src/client/util/CaptureManager.scss
@@ -1,8 +1,7 @@
 @import "../views/globalCssVariables";
 
-.settings-interface {
+.capture-interface {
     //background-color: whitesmoke !important;
-    color: grey;
     width: 450px;
 
     button {
@@ -21,14 +20,35 @@
     }
 }
 
-.settings-title {
-    font-size: 25px;
-    font-weight: bold;
-    padding-right: 10px;
+.capture-t1 {
+    display: flex;
+    justify-content: left;
+    align-items: center;
+    font-size: 20px;
+    font-family: 'Roboto';
+    font-weight: 600;
     color: black;
+
+    .recordButtonOutline {
+        border-radius: 100%;
+        width: 25px;
+        height: 25px;
+        margin-right: 10px;
+        border: solid 1px #a94442;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+    }
+    
+    .recordButtonInner {
+        border-radius: 100%;
+        width: 70%;
+        height: 70%;
+        background: #a94442;
+    }
 }
 
-.settings-username {
+.capture-t2 {
     font-size: 12px;
     padding-right: 15px;
     color: black;
@@ -39,13 +59,13 @@
     // left: 243;
 }
 
-.settings-section {
+.capture-block {
     display: flex;
     border-bottom: 1px solid grey;
     padding-bottom: 8px;
     padding-top: 6px;
 
-    .settings-section-title {
+    .capture-block-title {
         font-size: 16;
         font-weight: bold;
         text-align: left;
@@ -59,407 +79,21 @@
     }
 }
 
-
-.password-content {
-    display: flex;
-    flex-direction: column;
-
-    .password-content-inputs {
-        width: 100;
-        // margin-bottom: 10px;
-        font-size: 10px;
-
-        .password-inputs {
-            border: 1px solid rgb(160, 160, 160);
-            margin-bottom: 8px;
-            width: 130;
-            color: black;
-            border-radius: 5px;
-            padding:7px;
-            
-        }
-    }
-
-    .password-content-buttons {
-        //margin-left: 84px;
-        //width: 100;
-        padding: 7px;
-
-        .password-submit {
-            //margin-left: 85px;
-            margin-top: 5px;
-        }
-
-        .password-forgot {
-            //margin-left: 65px;
-            //margin-top: -20px;
-            font-size: 12px;
-            white-space: nowrap;
-        }
-    }
-}
-
-.accounts-content {
+.close-button {
+    position: absolute;
+    top: 10;
+    right: 10;
+    background:transparent;
+    border-radius:100%;
+    width: 25px;
+    height: 25px;
     display: flex;
+    align-items: center;
+    justify-content: center;
+    transition: 0.2s;
 }
 
-.modes-content {
-    display: flex;
-    margin-left: 10px;
-    font-size: 12px;
-
-    .modes-select {
-        // width: 170px;
-        width: 80%;
-        height: 35px;
-        margin-right: 10px;
-        color: black;
-        border-radius: 5px;
-
-        &:hover {
-            cursor: pointer;
-        }
-    }
-
-    .modes-playground,
-    .default-acl {
-        display: flex;
-        margin-left: 10px;
-        margin-top: 10px;
-        font-size: 10px;
-
-        .playground-check,
-        .acl-check {
-            margin-right: 5px;
-
-            &:hover {
-                cursor: pointer;
-            }
-        }
-
-        .playground-text {
-            color: black;
-            margin-right: 10px;
-            margin-top: 2;
-        }
-
-        .acl-text {
-            color: black;
-            margin-top: 2;
-            text-align: left;
-        }
-
-    }
-}
-
-.colorFlyout {
-    margin-top: 2px;
-    //margin-right: 18px;
-
-    &:hover {
-        cursor: pointer;
-    }
-
-    .colorFlyout-button {
-        width: 20px;
-        height: 20px;
-        border: 0.5px solid black;
-        border-radius: 5px;
-        padding-top: 3px;
-    }
-}
-
-.prefs-content{
-    text-align: left;
-}
-
-.appearances-content {
-    display: flex;
-    margin-top: 4px;
-    color: black;
-    font-size: 10px;
-
-    .preferences-color {
-        display: flex;
-        margin-top: 2px;
-
-        .preferences-color-text {
-            margin-top: 3px;
-            margin-right: 4;
-            flex: 1 1 auto;
-            text-align: left;
-        }
-
-        .colorFlyout {
-            align-self: flex-end;
-        }
-    }
-
-    .preferences-font {
-        //height: 23px;
-        margin-top: 2px;
-
-        .preferences-font-text {
-            color: black;
-            margin-top: 4;
-            margin-right: 4;
-            margin-bottom: 2px;
-            text-align: left;
-        }
-
-        .preferences-font-controls {
-            display: flex;
-            justify-content: space-between;
-        }
-
-        .font-select {
-            height: 35px;
-            color: black;
-            font-size: 9;
-            margin-right: 6;
-            border-radius: 5px;
-            width: 65%;
-
-            &:hover {
-                cursor: pointer;
-            }
-        }
-
-        .size-select {
-            height: 35px;
-            color: black;
-            font-size: 9;
-            border-radius: 5px;
-            width: 30%;
-
-            &:hover {
-                cursor: pointer;
-            }
-        }
-    }
-
-    .preferences-check {
-        color: black;
-        margin-right: 4;
-        margin-bottom: -3;
-        margin-left: 5;
-        margin-top: -1px;
-        display: inline-block;
-        padding-left: 5px;
-        text-align: left;
-    }
+.close-button:hover {
+    background: rgba(0,0,0,0.1);
 }
 
-.settings-interface {
-    display: flex;
-    flex-direction: column;
-
-    button {
-        width: auto;
-        align-self: center;
-        background: #252b33;
-        margin-right: 15px;
-
-        //margin-top: 4px;
-
-        &:hover {
-            background: $main-accent;
-        }
-    }
-
-    // .delete-button {
-    //     background: rgb(227, 86, 86);
-    // }
-
-    .close-button {
-        position: absolute;
-        right: 1em;
-        top: 1em;
-        cursor: pointer;
-    }
-
-    // .logout-button {
-    //     right: 355;
-    //     position: absolute;
-    // }
-
-    .settings-content {
-        background: #e4e4e4;
-        //border-radius: 6px;
-        padding: 10px;
-        //width: 560px;
-        flex: 1 1 auto;
-    }
-
-    .settings-top {
-        display: flex;
-        margin-bottom: 10px;
-    }
-
-
-    .error-text {
-        color: #C40233;
-        width: 300;
-        margin-left: -20;
-        font-size: 10;
-        margin-bottom: 4;
-        margin-top: -3;
-    }
-
-    .success-text {
-        width: 300;
-        margin-left: -20;
-        font-size: 10;
-        margin-bottom: 4;
-        margin-top: -3;
-        color: #009F6B;
-    }
-
-    .focus-span {
-        text-decoration: underline;
-    }
-
-    h1 {
-        color: #121721;
-        text-transform: uppercase;
-        letter-spacing: 2px;
-        font-size: 19;
-        margin-top: 0;
-        font-weight: bold;
-    }
-
-    .container {
-        display: block;
-        position: relative;
-        margin-top: 10px;
-        margin-bottom: 10px;
-        font-size: 22px;
-        -webkit-user-select: none;
-        -moz-user-select: none;
-        -ms-user-select: none;
-        user-select: none;
-        width: 700px;
-        min-width: 700px;
-        max-width: 700px;
-        text-align: left;
-        font-style: normal;
-        font-size: 15;
-        font-weight: normal;
-        padding: 0;
-
-        .padding {
-            padding: 0 0 0 20px;
-            color: black;
-        }
-
-    }
-}
-
-.settings-interface {
-    flex-direction: row;
-    position: relative;
-    min-height: 250px;
-    width: 100%;
-
-    .settings-content {
-        background-color: #fdfdfd;
-    }
-}
-
-.settings-panel {
-    position: relative;
-    min-width: 150px;
-    background-color: #e4e4e4;
-
-    .settings-user {
-        position: absolute;
-        bottom: 10px;
-        text-align: center;
-        left: 0;
-        right: 0;
-
-        .settings-username {
-            padding-right: 0px;
-        }
-
-        .logout-button {
-            margin-right: 2px;
-        }
-    }
-}
-
-.settings-tabs {
-    // font-size: 16px;
-    font-weight: 600;
-    color: black;
-
-    .tab-control {
-        padding: 10px;
-        border-bottom: 1px solid #9f9e9e;
-        cursor: pointer;
-
-        &.active {
-            background-color: #fdfdfd;
-        }
-    }
-}
-
-.settings-section-context {
-    width: 100%;
-}
-
-.tab-section {
-    display: none;
-    height: 200px;
-
-    &.active {
-        display: block;
-    }
-}
-
-.tab-content {
-    display: flex;
-    margin: 20px 0;
-
-    .tab-column {
-        flex: 0 0 50%;
-
-        .tab-column-title {
-            color: black;
-            font-size: 16px;
-            font-weight: bold;
-            margin-bottom: 16px;
-       }
-
-       .tab-column-title, .tab-column-content {
-           padding-left: 16px;
-       }
-
-    }
-
-}
-
-.tab-column button {
-    font-size: 9px;
-}
-
-@media only screen and (max-device-width: 480px) {
-    .settings-interface {
-        width: 80vw;
-        height: 400px;
-    }
-
-    .settings-interface .settings-body .settings-content input {
-        font-size: 30;
-    }
-
-    .settings-interface button {
-        width: 100%;
-        font-size: 30px;
-        background: #315a96;
-    }
-
-    .settings-interface .settings-heading {
-        font-size: 25;
-    }
-}
diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx
index f01fcd0d2..cea0c182f 100644
--- a/src/client/util/CaptureManager.tsx
+++ b/src/client/util/CaptureManager.tsx
@@ -2,16 +2,10 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import * as React from "react";
-import { ColorState, SketchPicker } from "react-color";
 import { Doc } from "../../fields/Doc";
 import { BoolCast, StrCast, Cast } from "../../fields/Types";
 import { addStyleSheet, addStyleSheetRule, Utils } from "../../Utils";
-import { GoogleAuthenticationManager } from "../apis/GoogleAuthenticationManager";
-import { DocServer } from "../DocServer";
-import { Networking } from "../Network";
 import { MainViewModal } from "../views/MainViewModal";
-import { CurrentUserUtils } from "./CurrentUserUtils";
-import { GroupManager } from "./GroupManager";
 import "./CaptureManager.scss";
 import { undoBatch } from "./UndoManager";
 const higflyout = require("@hig/flyout");
@@ -22,6 +16,7 @@ export const Flyout = higflyout.default;
 export class CaptureManager extends React.Component<{}> {
     public static Instance: CaptureManager;
     static _settingsStyle = addStyleSheet();
+    @observable _document: any;
     @observable isOpen: boolean = false; // whether the CaptureManager is to be displayed or not.
 
 
@@ -31,18 +26,27 @@ export class CaptureManager extends React.Component<{}> {
     }
 
     public close = action(() => this.isOpen = false);
-    public open = action(() => this.isOpen = true);
+    public open = action((doc: Doc) => {
+        this.isOpen = true;
+        this._document = doc;
+    });
 
 
-    @computed get colorsContent() {
-
-        return <div className="colors-content">
+    @computed get visibilityContent() {
 
+        return <div className="capture-block">
+            <div className="capture-block-title">Visibility
+                <div className="visibility-radio">
+                    <input type="radio" value="private" name="visibility" /> Private
+                    <input type="radio" value="public" name="visibility" /> Public
+                </div>
+            </div>
         </div>;
     }
 
-    @computed get formatsContent() {
-        return <div className="prefs-content">
+    @computed get linksContent() {
+        return <div className="capture-block">
+            <div className="capture-block-title">Links</div>
 
         </div>;
     }
@@ -52,11 +56,19 @@ export class CaptureManager extends React.Component<{}> {
 
 
     private get captureInterface() {
-        return <div className="settings-interface">
-            <div className="settings-panel">
-
+        return <div className="capture-interface">
+            <div className="capture-t1">
+                <div className="recordButtonOutline" style={{}}>
+                    <div className="recordButtonInner" style={{}}>
+                    </div>
+                </div>
+                Conversation Capture
             </div>
+            <div className="capture-t2">
 
+            </div>
+            {this.visibilityContent}
+            {this.linksContent}
             <div className="close-button" onClick={this.close}>
                 <FontAwesomeIcon icon={"times"} color="black" size={"lg"} />
             </div>
@@ -70,6 +82,9 @@ export class CaptureManager extends React.Component<{}> {
             isDisplayed={this.isOpen}
             interactive={true}
             closeOnExternalClick={this.close}
-            dialogueBoxStyle={{ width: "500px", height: "300px", background: Cast(Doc.SharingDoc().userColor, "string", null) }} />;
+            dialogueBoxStyle={{ width: "500px", height: "300px", border: "none", background: Cast(Doc.SharingDoc().userColor, "string", null) }}
+            overlayStyle={{ background: "black" }}
+            overlayDisplayedOpacity={0.6}
+        />
     }
 }
\ No newline at end of file
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 2fd9cb854..efd3d733f 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -188,10 +188,13 @@ export class LightboxView extends React.Component<LightboxViewProps> {
             LightboxView._future?.push(...DocListCast(tours[0][fieldKey]).reverse());
         } else {
             const coll = LightboxView._docTarget;
-            if (coll) {
+            const doc = LightboxView.LightboxDoc;
+            if (coll && doc) {
                 console.log('test');
+                console.log('target: ' + coll.title);
+                console.log('doc: ' + doc.title);
                 const fieldKey = Doc.LayoutFieldKey(coll);
-                LightboxView.SetLightboxDoc(coll, undefined);
+                LightboxView.SetLightboxDoc(doc);
                 // LightboxView.SetLightboxDoc(coll, undefined, [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + "-annotations"])]);
                 TabDocView.PinDoc(coll, { hidePresBox: true });
             }
diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx
index 7f91c0079..55dee005d 100644
--- a/src/client/views/MainViewModal.tsx
+++ b/src/client/views/MainViewModal.tsx
@@ -34,7 +34,7 @@ export class MainViewModal extends React.Component<MainViewOverlayProps> {
                 <div className="overlay"
                     onClick={this.props?.closeOnExternalClick}
                     style={{
-                        backgroundColor: "gainsboro",
+                        backgroundColor: "black",
                         ...(p.overlayStyle || {}),
                         opacity: p.isDisplayed ? overlayOpacity : 0
                     }}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 3321a8d8f..3299ea3a9 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -402,9 +402,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
         const doc = Docs.Create.ScreenshotDocument("", { _fitWidth: true, _width: 400, _height: 200, title: "screen snapshot", system: true, cloneFieldFilter: new List<string>(["system"]) });
         doc.x = 0;
         doc.y = 0;
+        doc.startRec = true;
         Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc);
         CollectionDockingView.AddSplit(doc, "right");
-        // doc.startRec = true;
     }
 
     @computed
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index 4c24dc5e1..cecc593f0 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -1,6 +1,6 @@
 import React = require("react");
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx";
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from "mobx";
 import { observer } from "mobx-react";
 import { DateField } from "../../../fields/DateField";
 import { Doc, WidthSym } from "../../../fields/Doc";
@@ -36,7 +36,7 @@ const ScreenshotDocument = makeInterface(documentSchema);
 @observer
 export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps, ScreenshotDocument>(ScreenshotDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ScreenshotBox, fieldKey); }
-    private _videoRef = React.createRef<HTMLVideoElement>();
+    private _videoRef: HTMLVideoElement | undefined | null;
     private _audioRec: any;
     private _videoRec: any;
     @observable _screenCapture = false;
@@ -56,7 +56,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
     }
 
     videoLoad = () => {
-        const aspect = this._videoRef.current!.videoWidth / this._videoRef.current!.videoHeight;
+        const aspect = this._videoRef!.videoWidth / this._videoRef!.videoHeight;
         const nativeWidth = Doc.NativeWidth(this.layoutDoc);
         const nativeHeight = Doc.NativeHeight(this.layoutDoc);
         if (!nativeWidth || !nativeHeight) {
@@ -69,9 +69,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
     componentDidMount() {
         this.dataDoc.nativeWidth = this.dataDoc.nativeHeight = 0;
         this.props.setContentView?.(this); // this tells the DocumentView that this ScreenshotBox is the "content" of the document.  this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link.
-        this._disposers.rec = reaction(() => this.rootDoc.startRec == true,
-            this.toggleRecording
-        );
     }
     componentWillUnmount() {
         const ind = DocUtils.ActiveRecordings.indexOf(this);
@@ -85,10 +82,22 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
     }
 
     @computed get content() {
+        trace();
+        console.log('content');
         const interactive = CurrentUserUtils.SelectedTool !== InkTool.None || !this.props.isSelected() ? "" : "-interactive";
-        return <video className={"videoBox-content" + interactive} key="video" ref={this._videoRef}
-            autoPlay={this._screenCapture}
-            style={{ width: this._screenCapture ? "100%" : undefined, height: this._screenCapture ? "100%" : undefined }}
+        return <video className={"videoBox-content" + interactive} key="video"
+            ref={r => {
+                console.log('ref: ', r);
+                this._videoRef = r;
+                setTimeout(() => {
+                    if (this.rootDoc.startRec && this._videoRef) { // TODO glr: use mediaState
+                        this.toggleRecording();
+                        this.rootDoc.startRec = undefined;
+                    }
+                }, 1000);
+            }}
+            autoPlay={true}
+            style={{ width: "100%", height: "100%" }}
             onCanPlay={this.videoLoad}
             controls={true}
             onClick={e => e.preventDefault()}>
@@ -99,14 +108,11 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
 
     toggleRecording = action(async () => {
         console.log("toggleRecording");
-        console.log("2:" + this._videoRef.current!.srcObject);
-        if (this._screenCapture) {
-            CaptureManager.Instance.open(this.rootDoc);
-        } else {
-            console.log("opening");
-        }
+        console.log("2:" + this._videoRef!.srcObject);
+
         this._screenCapture = !this._screenCapture;
         if (this._screenCapture) {
+            console.log("opening");
             this._audioRec = new MediaRecorder(await navigator.mediaDevices.getUserMedia({ audio: true }));
             const aud_chunks: any = [];
             this._audioRec.ondataavailable = (e: any) => aud_chunks.push(e.data);
@@ -116,12 +122,13 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
                     this.dataDoc[this.props.fieldKey + "-audio"] = new AudioField(Utils.prepend(result.accessPaths.agnostic.client));
                 }
             };
-            this._videoRef.current!.srcObject = await (navigator.mediaDevices as any).getDisplayMedia({ video: true });
-            this._videoRec = new MediaRecorder(this._videoRef.current!.srcObject);
+            this._videoRef!.srcObject = await (navigator.mediaDevices as any).getDisplayMedia({ video: true });
+            this._videoRec = new MediaRecorder(this._videoRef!.srcObject);
             const vid_chunks: any = [];
             this._videoRec.onstart = () => this.dataDoc[this.props.fieldKey + "-recordingStart"] = new DateField(new Date());
             this._videoRec.ondataavailable = (e: any) => vid_chunks.push(e.data);
             this._videoRec.onstop = async (e: any) => {
+                console.log("onStop: video end");
                 const file = new File(vid_chunks, `${this.rootDoc[Id]}.mkv`, { type: vid_chunks[0].type, lastModified: Date.now() });
                 const [{ result }] = await Networking.UploadFilesToServer(file);
                 this.dataDoc[this.fieldKey + "-duration"] = (new Date().getTime() - this.recordingStart!) / 1000;
@@ -143,6 +150,9 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
             this.dataDoc.mediaState = "paused";
             const ind = DocUtils.ActiveRecordings.indexOf(this);
             ind !== -1 && (DocUtils.ActiveRecordings.splice(ind, 1));
+
+            CaptureManager.Instance.open(this.rootDoc);
+            console.log("closing");
         }
     });
 
@@ -163,62 +173,58 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
     formattedPanelHeight = () => Math.max(0, this.props.PanelHeight() - this.videoPanelHeight());
     render() {
         TraceMobx();
-        return this.rootDoc.startRec ?
-            <div className="mini-viewer">
-
+        console.log('rendering');
+        return <div className="videoBox" onContextMenu={this.specificContextMenu} style={{ width: "100%", height: "100%" }} >
+            <div className="videoBox-viewer" >
+                <div style={{ position: "relative", height: this.videoPanelHeight() }}>
+                    <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
+                        PanelHeight={this.videoPanelHeight}
+                        PanelWidth={this.props.PanelWidth}
+                        focus={this.props.focus}
+                        isSelected={this.props.isSelected}
+                        isAnnotationOverlay={true}
+                        select={emptyFunction}
+                        isContentActive={returnFalse}
+                        scaling={returnOne}
+                        whenChildContentsActiveChanged={emptyFunction}
+                        removeDocument={returnFalse}
+                        moveDocument={returnFalse}
+                        addDocument={returnFalse}
+                        CollectionView={undefined}
+                        ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+                        renderDepth={this.props.renderDepth + 1}
+                        ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
+                        {this.contentFunc}
+                    </CollectionFreeFormView></div>
+                <div style={{ position: "relative", height: this.formattedPanelHeight() }}>
+                    <FormattedTextBox {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
+                        Document={this.dataDoc[this.fieldKey + "-dictation"]}
+                        fieldKey={"text"}
+                        PanelHeight={this.formattedPanelHeight}
+                        PanelWidth={this.props.PanelWidth}
+                        focus={this.props.focus}
+                        isSelected={this.props.isSelected}
+                        isAnnotationOverlay={true}
+                        select={emptyFunction}
+                        isContentActive={returnFalse}
+                        scaling={returnOne}
+                        xMargin={25}
+                        yMargin={10}
+                        whenChildContentsActiveChanged={emptyFunction}
+                        removeDocument={returnFalse}
+                        moveDocument={returnFalse}
+                        addDocument={returnFalse}
+                        CollectionView={undefined}
+                        ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+                        renderDepth={this.props.renderDepth + 1}
+                        ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
+                    </FormattedTextBox></div>
             </div>
-            :
-            <div className="videoBox" onContextMenu={this.specificContextMenu} style={{ width: "100%", height: "100%" }} >
-                <div className="videoBox-viewer" >
-                    <div style={{ position: "relative", height: this.videoPanelHeight() }}>
-                        <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
-                            PanelHeight={this.videoPanelHeight}
-                            PanelWidth={this.props.PanelWidth}
-                            focus={this.props.focus}
-                            isSelected={this.props.isSelected}
-                            isAnnotationOverlay={true}
-                            select={emptyFunction}
-                            isContentActive={returnFalse}
-                            scaling={returnOne}
-                            whenChildContentsActiveChanged={emptyFunction}
-                            removeDocument={returnFalse}
-                            moveDocument={returnFalse}
-                            addDocument={returnFalse}
-                            CollectionView={undefined}
-                            ScreenToLocalTransform={this.props.ScreenToLocalTransform}
-                            renderDepth={this.props.renderDepth + 1}
-                            ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
-                            {this.contentFunc}
-                        </CollectionFreeFormView></div>
-                    <div style={{ position: "relative", height: this.formattedPanelHeight() }}>
-                        <FormattedTextBox {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
-                            Document={this.dataDoc[this.fieldKey + "-dictation"]}
-                            fieldKey={"text"}
-                            PanelHeight={this.formattedPanelHeight}
-                            PanelWidth={this.props.PanelWidth}
-                            focus={this.props.focus}
-                            isSelected={this.props.isSelected}
-                            isAnnotationOverlay={true}
-                            select={emptyFunction}
-                            isContentActive={returnFalse}
-                            scaling={returnOne}
-                            xMargin={25}
-                            yMargin={10}
-                            whenChildContentsActiveChanged={emptyFunction}
-                            removeDocument={returnFalse}
-                            moveDocument={returnFalse}
-                            addDocument={returnFalse}
-                            CollectionView={undefined}
-                            ScreenToLocalTransform={this.props.ScreenToLocalTransform}
-                            renderDepth={this.props.renderDepth + 1}
-                            ContainingCollectionDoc={this.props.ContainingCollectionDoc}>
-                        </FormattedTextBox></div>
+            {!this.props.isSelected() ? (null) : <div className="screenshotBox-uiButtons">
+                <div className="screenshotBox-recorder" key="snap" onPointerDown={this.toggleRecording} >
+                    <FontAwesomeIcon icon="file" size="lg" />
                 </div>
-                {!this.props.isSelected() ? (null) : <div className="screenshotBox-uiButtons">
-                    <div className="screenshotBox-recorder" key="snap" onPointerDown={this.toggleRecording} >
-                        <FontAwesomeIcon icon="file" size="lg" />
-                    </div>
-                </div>}
-            </div >;
+            </div>}
+        </div >;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index a1fc77a92..f15d51764 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -57,6 +57,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
     @computed get targetDoc() { return Cast(this.rootDoc.presentationTargetDoc, Doc, null) || this.rootDoc; }
 
     componentDidMount() {
+        this.layoutDoc.hideLinkButton = true;
         this._heightDisposer = reaction(() => [this.rootDoc.presExpandInlineButton, this.collapsedHeight],
             params => this.layoutDoc._height = NumCast(params[1]) + (Number(params[0]) ? 100 : 0), { fireImmediately: true });
     }
@@ -114,6 +115,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
                     searchFilterDocs={this.props.searchFilterDocs}
                     ContainingCollectionView={undefined}
                     ContainingCollectionDoc={undefined}
+                    hideLinkButton={true}
                 />
                 <div className="presItem-embeddedMask" />
             </div>;
-- 
cgit v1.2.3-70-g09d2


From 821f1395198e4fe4cb06192ce1ba1a2864914159 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 7 Apr 2021 15:44:17 -0400
Subject: can't make two different views of a recording.

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

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

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 3299ea3a9..e0c68e51c 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -403,7 +403,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
         doc.x = 0;
         doc.y = 0;
         doc.startRec = true;
-        Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc);
+        //Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc);
         CollectionDockingView.AddSplit(doc, "right");
     }
 
-- 
cgit v1.2.3-70-g09d2


From d0b90a0a7849cdc06f4332df9ad6eae5342520ca Mon Sep 17 00:00:00 2001
From: Geireann <60007097+geireann@users.noreply.github.com>
Date: Thu, 8 Apr 2021 04:07:42 -0400
Subject: changes

---
 src/client/util/CaptureManager.scss                | 84 ++++++++++++++++++++--
 src/client/util/CaptureManager.tsx                 | 66 ++++++++++++++---
 src/client/views/collections/CollectionMenu.tsx    |  3 +-
 .../collections/CollectionStackedTimeline.tsx      |  8 +--
 src/client/views/nodes/DocumentView.tsx            |  2 +-
 src/client/views/nodes/VideoBox.tsx                |  3 +-
 6 files changed, 146 insertions(+), 20 deletions(-)

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

diff --git a/src/client/util/CaptureManager.scss b/src/client/util/CaptureManager.scss
index 8447bd2d5..71539ee1e 100644
--- a/src/client/util/CaptureManager.scss
+++ b/src/client/util/CaptureManager.scss
@@ -60,8 +60,7 @@
 }
 
 .capture-block {
-    display: flex;
-    border-bottom: 1px solid grey;
+    display: block;
     padding-bottom: 8px;
     padding-top: 6px;
 
@@ -72,10 +71,87 @@
         color: black;
         width: 80;
         margin-right: 50px;
+        margin-bottom: 5px;
+    }
+
+    .capture-block-list {
+        height: 135px;
+        width: calc(100% + 15px);
+        overflow: scroll;
+    }
+
+    .capture-block-radio {
+        font-size: 12;
+        display: block;
+        font-weight: normal;
+
+        .radio-container {
+            display: flex;
+            justify-content: left;
+            align-items: center;
+            font-size: 13px;
+            font-family: 'Roboto';
+        }
     }
 
-    &:last-child {
-        border-bottom: none;
+    .list-item {
+        display: flex;
+        height: 25px;
+        font-family: 'Roboto';
+        font-size: 13px;
+
+        .number {
+            width: 20px;
+            height: 20px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            background-color: #BDDBE8;
+            border-radius: 100%;
+            font-weight: 800;
+            margin-right: 5px;
+        }
+    }
+
+    .buttons {
+        display: flex;
+        position: absolute;
+        bottom: 0;
+        right: 15;
+        justify-content: flex-end;
+        align-items: center;
+        height: 60px;
+
+        .save {
+            cursor: pointer;
+            width: 80px;
+            height: 40px;
+            font-size: 14px;
+            display: flex;
+            font-weight: bold;
+            justify-content: center;
+            align-items: center;
+            background: #337ab7;
+            color: whitesmoke;
+            border-radius: 5px;
+            text-transform: uppercase;
+        }
+
+        .cancel {
+            cursor: pointer;
+            width: 80px;
+            height: 40px;
+            font-size: 14px;
+            display: flex;
+            font-weight: 100;
+            justify-content: center;
+            align-items: center;
+            background: #ccc;
+            color: black;
+            border-radius: 5px;
+            text-transform: uppercase;
+            margin-left: 10px;
+        }
     }
 }
 
diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx
index cea0c182f..c38337c91 100644
--- a/src/client/util/CaptureManager.tsx
+++ b/src/client/util/CaptureManager.tsx
@@ -2,11 +2,14 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import * as React from "react";
-import { Doc } from "../../fields/Doc";
+import { convertToObject } from "typescript";
+import { Doc, DocListCast } from "../../fields/Doc";
 import { BoolCast, StrCast, Cast } from "../../fields/Types";
 import { addStyleSheet, addStyleSheetRule, Utils } from "../../Utils";
+import { LightboxView } from "../views/LightboxView";
 import { MainViewModal } from "../views/MainViewModal";
 import "./CaptureManager.scss";
+import { SelectionManager } from "./SelectionManager";
 import { undoBatch } from "./UndoManager";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
@@ -35,23 +38,69 @@ export class CaptureManager extends React.Component<{}> {
     @computed get visibilityContent() {
 
         return <div className="capture-block">
-            <div className="capture-block-title">Visibility
-                <div className="visibility-radio">
-                    <input type="radio" value="private" name="visibility" /> Private
-                    <input type="radio" value="public" name="visibility" /> Public
+            <div className="capture-block-title">Visibility</div>
+            <div className="capture-block-radio">
+                <div className="radio-container">
+                    <input type="radio" value="private" name="visibility" style={{ margin: 0, marginRight: 5 }} /> Private
+                </div>
+                <div className="radio-container">
+                    <input type="radio" value="public" name="visibility" style={{ margin: 0, marginRight: 5 }} /> Public
                 </div>
             </div>
         </div>;
     }
 
     @computed get linksContent() {
+        const doc = this._document;
+        const order: JSX.Element[] = [];
+        if (doc) {
+            console.log('title', doc.title);
+            console.log('links', doc.links);
+            const linkDocs = DocListCast(doc.links);
+            const firstDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor1 as Doc, doc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, doc)); // link docs where 'doc' is anchor1
+            const secondDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor2 as Doc, doc) || Doc.AreProtosEqual((linkDoc.anchor2 as Doc).annotationOn as Doc, doc)); // link docs where 'doc' is anchor2
+            linkDocs.forEach((l, i) => {
+                if (l) {
+                    console.log(i, (l.anchor1 as Doc).title);
+                    console.log(i, (l.anchor2 as Doc).title);
+                    order.push(
+                        <div className="list-item">
+                            <div className="number">{i}</div>
+                            {(l.anchor1 as Doc).title}
+                        </div>
+                    );
+                }
+            });
+        }
+
         return <div className="capture-block">
             <div className="capture-block-title">Links</div>
-
+            <div className="capture-block-list">
+                {order}
+            </div>
         </div>;
     }
 
-
+    @computed get closeButtons() {
+        return <div className="capture-block">
+            <div className="buttons">
+                <div className="save" onClick={() => {
+                    LightboxView.SetLightboxDoc(this._document);
+                    this.close();
+                }}>
+                    Save
+                </div>
+                <div className="cancel" onClick={() => {
+                    const selected = SelectionManager.Views().slice();
+                    SelectionManager.DeselectAll();
+                    selected.map(dv => dv.props.removeDocument?.(dv.props.Document));
+                    this.close();
+                }}>
+                    Cancel
+                </div>
+            </div>
+        </div>
+    }
 
 
 
@@ -72,6 +121,7 @@ export class CaptureManager extends React.Component<{}> {
             <div className="close-button" onClick={this.close}>
                 <FontAwesomeIcon icon={"times"} color="black" size={"lg"} />
             </div>
+            {this.closeButtons}
         </div>;
 
     }
@@ -82,7 +132,7 @@ export class CaptureManager extends React.Component<{}> {
             isDisplayed={this.isOpen}
             interactive={true}
             closeOnExternalClick={this.close}
-            dialogueBoxStyle={{ width: "500px", height: "300px", border: "none", background: Cast(Doc.SharingDoc().userColor, "string", null) }}
+            dialogueBoxStyle={{ width: "500px", height: "350px", border: "none", background: "whitesmoke" }}
             overlayStyle={{ background: "black" }}
             overlayDisplayedOpacity={0.6}
         />
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 3299ea3a9..6816b4739 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -403,7 +403,6 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
         doc.x = 0;
         doc.y = 0;
         doc.startRec = true;
-        Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc);
         CollectionDockingView.AddSplit(doc, "right");
     }
 
@@ -548,8 +547,8 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
                         <div className="collectionMenu-divider" key="divider1"></div>
                         {this.aliasButton}
                         {/* {this.pinButton} */}
-                        {/* {this.pinWithViewButton} */}
                         {this.toggleOverlayButton}
+                        {this.pinWithViewButton}
                         <div className="collectionMenu-divider" key="divider2"></div>
                         {this.subChrome}
                         <div className="collectionMenu-divider" key="divider3"></div>
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 6a1242f20..4f9f297a2 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -234,15 +234,15 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument
         return level;
     }
 
-    dictationHeight = () => this.props.PanelHeight() / 3;
-    timelineContentHeight = () => this.props.PanelHeight() * 2 / 3;
+    dictationHeight = () => "50%";
+    timelineContentHeight = () => this.props.PanelHeight() / 2;
     dictationScreenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.timelineContentHeight());
     @computed get renderDictation() {
         const dictation = Cast(this.dataDoc[this.props.dictationKey], Doc, null);
-        return !dictation ? (null) : <div style={{ position: "absolute", height: this.dictationHeight(), top: this.timelineContentHeight(), background: "tan" }}>
+        return !dictation ? (null) : <div style={{ position: "absolute", height: this.dictationHeight(), top: "50%", background: "tan" }}>
             <DocumentView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
                 Document={dictation}
-                PanelHeight={this.dictationHeight}
+                PanelHeight={() => "100%"}
                 isAnnotationOverlay={true}
                 isDocumentActive={returnFalse}
                 select={emptyFunction}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 26cf52f17..153603c3c 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1105,7 +1105,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                         position: this.props.Document.isInkMask ? "absolute" : undefined,
                         transform: `translate(${this.centeringX}px, ${this.centeringY}px)`,
                         width: xshift() ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`,
-                        height: yshift() ?? (this.fitWidth ? `${this.panelHeight}px` :
+                        height: this.props.Document.type === DocumentType.VID ? "100%" : yshift() ?? (this.fitWidth ? `${this.panelHeight}px` :
                             `${100 * this.effectiveNativeHeight / this.effectiveNativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%`),
                     }}>
                     <DocumentViewInternal {...this.props}
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index fb58ddefc..ab072a97f 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -417,12 +417,13 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
 
     onTimelineHdlDown = action((e: React.PointerEvent) => {
         this._clicking = true;
+        console.log('timeline click');
         setupMoveUpEvents(this, e,
             action((e: PointerEvent) => {
                 this._clicking = false;
                 if (this.isContentActive()) {
                     const local = this.props.ScreenToLocalTransform().scale(this.props.scaling?.() || 1).transformPoint(e.clientX, e.clientY);
-                    this.layoutDoc._timelineHeightPercent = Math.max(0, Math.min(100, local[1] / this.props.PanelHeight() * 100));
+                    this.layoutDoc._timelineHeightPercent = 50;
                 }
                 return false;
             }), emptyFunction,
-- 
cgit v1.2.3-70-g09d2


From 9669ebd0c0e76bbfbbc898e8b379cff41b1031ed Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 11 Apr 2021 12:07:10 -0400
Subject: some cleanup of demo_changes

---
 src/client/views/collections/CollectionMenu.tsx    |  2 +-
 .../collections/CollectionStackedTimeline.tsx      | 17 ++++++++-------
 src/client/views/nodes/PresBox.tsx                 | 24 +++++++++-------------
 src/client/views/nodes/ScreenshotBox.tsx           | 12 +----------
 src/client/views/nodes/VideoBox.tsx                |  1 -
 src/client/views/nodes/WebBox.tsx                  |  5 +++++
 6 files changed, 27 insertions(+), 34 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index f56f12c67..337595f1c 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -15,7 +15,7 @@ import { RichTextField } from "../../../fields/RichTextField";
 import { listSpec } from "../../../fields/Schema";
 import { ScriptField } from "../../../fields/ScriptField";
 import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
-import { DeepCopy, emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils";
+import { emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils";
 import { DocumentType } from "../../documents/DocumentTypes";
 import { CurrentUserUtils } from "../../util/CurrentUserUtils";
 import { DragManager } from "../../util/DragManager";
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 782726456..ab9c4aa2c 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -234,16 +234,16 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument
         return level;
     }
 
-    dictationHeight = () => "50%";
-    documentHeight = () => "100%";
-    timelineContentHeight = () => this.props.PanelHeight() / 2;
+    dictationHeightPercent = 50;
+    dictationHeight = () => `${this.dictationHeightPercent}%`;
+    timelineContentHeight = () => this.props.PanelHeight() * this.dictationHeightPercent / 100;
     dictationScreenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.timelineContentHeight());
     @computed get renderDictation() {
         const dictation = Cast(this.dataDoc[this.props.dictationKey], Doc, null);
-        return !dictation ? (null) : <div style={{ position: "absolute", height: this.dictationHeight(), top: "50%", background: "tan" }}>
+        return !dictation ? (null) : <div style={{ position: "absolute", height: this.dictationHeight(), top: this.timelineContentHeight(), background: "tan" }}>
             <DocumentView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit}
                 Document={dictation}
-                PanelHeight={this.documentHeight}
+                PanelHeight={this.dictationHeight}
                 isAnnotationOverlay={true}
                 isDocumentActive={returnFalse}
                 select={emptyFunction}
@@ -349,8 +349,11 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
             (time) => {
                 const dictationDoc = Cast(this.props.layoutDoc["data-dictation"], Doc, null);
                 const isDictation = dictationDoc && DocListCast(this.props.mark.links).some(link => Cast(link.anchor1, Doc, null)?.annotationOn === dictationDoc);
-                if ((!LightboxView.LightboxDoc
-                    /*isDictation || !Doc.AreProtosEqual(LightboxView.LightboxDoc, this.props.layoutDoc)*/) && DocListCast(this.props.mark.links).length &&
+                if (!LightboxView.LightboxDoc
+                    // bcz: when should links be followed?  we don't want to move away from the video to follow a link but we can open it in a sidebar/etc.  But we don't know that upfront.
+                    // for now, we won't follow any links when the lightbox is oepn to avoid "losing" the video.
+                    /*(isDictation || !Doc.AreProtosEqual(LightboxView.LightboxDoc, this.props.layoutDoc))*/
+                    && DocListCast(this.props.mark.links).length &&
                     time > NumCast(this.props.mark[this.props.startTag]) &&
                     time < NumCast(this.props.mark[this.props.endTag]) &&
                     this._lastTimecode < NumCast(this.props.mark[this.props.startTag])) {
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 446db3549..f3fb6ff17 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -5,7 +5,7 @@ import { action, computed, IReactionDisposer, observable, ObservableMap, reactio
 import { observer } from "mobx-react";
 import { ColorState, SketchPicker } from "react-color";
 import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal';
-import { Doc, DocListCast, DocListCastAsync } from "../../../fields/Doc";
+import { Doc, DocListCast, DocListCastAsync, FieldResult } from "../../../fields/Doc";
 import { documentSchema } from "../../../fields/documentSchemas";
 import { InkTool } from "../../../fields/InkField";
 import { List } from "../../../fields/List";
@@ -247,11 +247,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
         // }
     }
 
-    stopTempMedia = (targetDoc: Doc) => {
-        if (targetDoc.type === DocumentType.AUDIO) {
+    stopTempMedia = (targetDocField: FieldResult) => {
+        const targetDoc = Cast(targetDocField, Doc, null);
+        if (targetDoc?.type === DocumentType.AUDIO) {
             if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]);
             targetDoc._audioStop = true;
-        } else if (targetDoc.type === DocumentType.VID) {
+        } else if (targetDoc?.type === DocumentType.VID) {
             if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]);
             targetDoc._triggerVideoStop = true;
         }
@@ -331,14 +332,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             this.rootDoc._itemIndex = index;
             const activeItem: Doc = this.activeItem;
             const targetDoc: Doc = this.targetDoc;
-            if (from && from.mediaStopTriggerList && this.layoutDoc.presStatus !== PresStatus.Edit) {
-                const mediaDocList = DocListCast(from.mediaStopTriggerList);
-                mediaDocList.forEach((doc) => {
-                    this.stopTempMedia(Cast(doc.presentationTargetDoc, Doc, null));
-                });
+            if (from?.mediaStopTriggerList && this.layoutDoc.presStatus !== PresStatus.Edit) {
+                DocListCast(from.mediaStopTriggerList).forEach(this.stopTempMedia);
             }
-            if (from && from.mediaStop === "auto" && this.layoutDoc.presStatus !== PresStatus.Edit) {
-                this.stopTempMedia(Cast(from.presentationTargetDoc, Doc, null));
+            if (from?.mediaStop === "auto" && this.layoutDoc.presStatus !== PresStatus.Edit) {
+                this.stopTempMedia(from.presentationTargetDoc);
             }
             // If next slide is audio / video 'Play automatically' then the next slide should be played
             if (this.layoutDoc.presStatus !== PresStatus.Edit && (targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && (activeItem.mediaStart === "auto")) {
@@ -577,9 +575,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
             if (this._presTimer) clearTimeout(this._presTimer);
             this.layoutDoc.presStatus = PresStatus.Manual;
             this.layoutDoc.presLoop = false;
-            this.childDocs.forEach((doc) => {
-                this.stopTempMedia(Cast(doc.presentationTargetDoc, Doc, null));
-            });
+            this.childDocs.forEach(this.stopTempMedia);
         }
     }
 
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index cecc593f0..6449c99a1 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -36,7 +36,7 @@ const ScreenshotDocument = makeInterface(documentSchema);
 @observer
 export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps, ScreenshotDocument>(ScreenshotDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ScreenshotBox, fieldKey); }
-    private _videoRef: HTMLVideoElement | undefined | null;
+    private _videoRef: HTMLVideoElement | null = null;
     private _audioRec: any;
     private _videoRec: any;
     @observable _screenCapture = false;
@@ -82,12 +82,9 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
     }
 
     @computed get content() {
-        trace();
-        console.log('content');
         const interactive = CurrentUserUtils.SelectedTool !== InkTool.None || !this.props.isSelected() ? "" : "-interactive";
         return <video className={"videoBox-content" + interactive} key="video"
             ref={r => {
-                console.log('ref: ', r);
                 this._videoRef = r;
                 setTimeout(() => {
                     if (this.rootDoc.startRec && this._videoRef) { // TODO glr: use mediaState
@@ -107,12 +104,8 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
     }
 
     toggleRecording = action(async () => {
-        console.log("toggleRecording");
-        console.log("2:" + this._videoRef!.srcObject);
-
         this._screenCapture = !this._screenCapture;
         if (this._screenCapture) {
-            console.log("opening");
             this._audioRec = new MediaRecorder(await navigator.mediaDevices.getUserMedia({ audio: true }));
             const aud_chunks: any = [];
             this._audioRec.ondataavailable = (e: any) => aud_chunks.push(e.data);
@@ -128,7 +121,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
             this._videoRec.onstart = () => this.dataDoc[this.props.fieldKey + "-recordingStart"] = new DateField(new Date());
             this._videoRec.ondataavailable = (e: any) => vid_chunks.push(e.data);
             this._videoRec.onstop = async (e: any) => {
-                console.log("onStop: video end");
                 const file = new File(vid_chunks, `${this.rootDoc[Id]}.mkv`, { type: vid_chunks[0].type, lastModified: Date.now() });
                 const [{ result }] = await Networking.UploadFilesToServer(file);
                 this.dataDoc[this.fieldKey + "-duration"] = (new Date().getTime() - this.recordingStart!) / 1000;
@@ -152,7 +144,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
             ind !== -1 && (DocUtils.ActiveRecordings.splice(ind, 1));
 
             CaptureManager.Instance.open(this.rootDoc);
-            console.log("closing");
         }
     });
 
@@ -173,7 +164,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
     formattedPanelHeight = () => Math.max(0, this.props.PanelHeight() - this.videoPanelHeight());
     render() {
         TraceMobx();
-        console.log('rendering');
         return <div className="videoBox" onContextMenu={this.specificContextMenu} style={{ width: "100%", height: "100%" }} >
             <div className="videoBox-viewer" >
                 <div style={{ position: "relative", height: this.videoPanelHeight() }}>
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 3b0fb4091..fb58ddefc 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -417,7 +417,6 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
 
     onTimelineHdlDown = action((e: React.PointerEvent) => {
         this._clicking = true;
-        console.log('timeline click');
         setupMoveUpEvents(this, e,
             action((e: PointerEvent) => {
                 this._clicking = false;
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 2f2b242f5..a632d1fcc 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -81,7 +81,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         runInAction(() => {
             this._url = this.webField?.toString() || "";
             this._annotationKey = "annotations-" + this.urlHash(this._url);
+            // bcz: this is messy.  logically, setting the url alone should direct where annotations should go.  But 
+            // right now we need to set doc.annotation-active to be the field suffix for the annotations
+            // and we need to set a computed field to copy the annotations to where everyone else expects them in doc.field-annotations
+            // TODO: always write annotations to doc.field-anotations and then copy them to doc.field-annotaitons-hash only when the page is changed.
             this.dataDoc["annotation-active"] = this._annotationKey;
+            // bcz: need to make sure that doc.data-annotations points to the currently active web page's annotations (this could/should be in the constructor)
             this.dataDoc[this.fieldKey + "-annotations"] = ComputedField.MakeFunction(`copyField(this["${this.fieldKey}-"+this["annotation-active"]])`);
         });
 
-- 
cgit v1.2.3-70-g09d2


From 470240a50c3af2ff29a6d61ee256374e70933eb9 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 11 Apr 2021 12:34:51 -0400
Subject: updated startRect to use mediaState and added pendingRecording as an
 option.

---
 src/client/documents/Documents.ts               | 5 +++--
 src/client/util/CurrentUserUtils.ts             | 2 +-
 src/client/views/collections/CollectionMenu.tsx | 5 +----
 src/client/views/nodes/AudioBox.tsx             | 2 +-
 src/client/views/nodes/ScreenshotBox.tsx        | 3 +--
 5 files changed, 7 insertions(+), 10 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 96aa43c79..219890945 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -164,6 +164,7 @@ export class DocumentOptions {
     version?: string; // version identifier for a document
     label?: string;
     hidden?: boolean;
+    mediaState?: string; // status of media document: "pendingRecording", "recording", "paused", "playing"
     autoPlayAnchors?: boolean; // whether to play audio/video when an anchor is clicked in a stackedTimeline.
     dontPlayLinkOnSelect?: boolean;  // whether an audio/video should start playing when a link is followed to it.
     toolTip?: string; // tooltip to display on hover
@@ -703,8 +704,8 @@ export namespace Docs {
             return InstanceFromProto(Prototypes.get(DocumentType.WEBCAM), "", options);
         }
 
-        export function ScreenshotDocument(url: string, options: DocumentOptions = {}) {
-            return InstanceFromProto(Prototypes.get(DocumentType.SCREENSHOT), "", options);
+        export function ScreenshotDocument(title: string, options: DocumentOptions = {}) {
+            return InstanceFromProto(Prototypes.get(DocumentType.SCREENSHOT), "", { ...options, title });
         }
 
         export function ComparisonDocument(options: DocumentOptions = { title: "Comparison Box" }) {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 0875d9be7..cb8bf5a7f 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -423,7 +423,7 @@ export class CurrentUserUtils {
             ((doc.emptyScript as Doc).proto as Doc)["dragFactory-count"] = 0;
         }
         if (doc.emptyScreenshot === undefined) {
-            doc.emptyScreenshot = Docs.Create.ScreenshotDocument("", { _fitWidth: true, _width: 400, _height: 200, title: "screen snapshot", system: true, cloneFieldFilter: new List<string>(["system"]) });
+            doc.emptyScreenshot = Docs.Create.ScreenshotDocument("empty screenshot", { _fitWidth: true, _width: 400, _height: 200, system: true, cloneFieldFilter: new List<string>(["system"]) });
         }
         if (doc.emptyAudio === undefined) {
             doc.emptyAudio = Docs.Create.AudioDocument(nullAudio, { _width: 200, title: "audio recording", system: true, cloneFieldFilter: new List<string>(["system"]) });
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 337595f1c..a26953ff6 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -399,10 +399,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
     @undoBatch
     @action
     startRecording = () => {
-        const doc = Docs.Create.ScreenshotDocument("", { _fitWidth: true, _width: 400, _height: 200, title: "screen snapshot", system: true, cloneFieldFilter: new List<string>(["system"]) });
-        doc.x = 0;
-        doc.y = 0;
-        doc.startRec = true;
+        const doc = Docs.Create.ScreenshotDocument("screen recording", { _fitWidth: true, _width: 400, _height: 200, mediaState: "pendingRecording" });
         //Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, doc);
         CollectionDockingView.AddSplit(doc, "right");
     }
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 85899578c..a2e36f12e 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -53,7 +53,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
     @observable _position: number = 0;
     @observable _waveHeight: Opt<number> = this.layoutDoc._height;
     @observable _paused: boolean = false;
-    @computed get mediaState(): undefined | "recording" | "paused" | "playing" { return this.dataDoc.mediaState as (undefined | "recording" | "paused" | "playing"); }
+    @computed get mediaState(): undefined | "pendingRecording" | "recording" | "paused" | "playing" { return this.dataDoc.mediaState as (undefined | "pendingRecording" | "recording" | "paused" | "playing"); }
     set mediaState(value) { this.dataDoc.mediaState = value; }
     public static SetScrubTime = action((timeInMillisFrom1970: number) => { AudioBox._scrubTime = 0; AudioBox._scrubTime = timeInMillisFrom1970; });
     @computed get recordingStart() { return Cast(this.dataDoc[this.props.fieldKey + "-recordingStart"], DateField)?.date.getTime(); }
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index 73fe8d68a..c4f8d1143 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -84,9 +84,8 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
             ref={r => {
                 this._videoRef = r;
                 setTimeout(() => {
-                    if (this.rootDoc.startRec && this._videoRef) { // TODO glr: use mediaState
+                    if (this.rootDoc.mediaState === "pendingRecording" && this._videoRef) { // TODO glr: use mediaState
                         this.toggleRecording();
-                        this.rootDoc.startRec = undefined;
                     }
                 }, 1000);
             }}
-- 
cgit v1.2.3-70-g09d2


From 3ca56576e187e2f3cc87770b0fbdf8aa6cae73f3 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 14 Apr 2021 23:12:19 -0400
Subject: fixed image templates to set/use the appropriate nativewidth/height.
 fixed carousel views and style provider to better support properties for
 components of a document view.  fixed menus to show text options when
 captions and other sub text components are focused.

---
 src/client/views/DocComponent.tsx                  |  4 +-
 src/client/views/StyleProvider.tsx                 |  3 +-
 .../views/collections/CollectionCarousel3DView.tsx | 23 +----------
 .../views/collections/CollectionCarouselView.tsx   | 46 +++++++---------------
 src/client/views/collections/CollectionMenu.scss   |  2 +-
 src/client/views/collections/CollectionMenu.tsx    |  3 ++
 src/client/views/collections/TabDocView.tsx        |  3 +-
 src/client/views/nodes/ImageBox.tsx                |  4 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |  6 ++-
 src/fields/Doc.ts                                  |  4 +-
 10 files changed, 35 insertions(+), 63 deletions(-)

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

diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index c017b7015..3c565fd62 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -124,8 +124,8 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
                 return ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name, scale: "number" })?.script.run({ self: this.rootDoc, this: this.layoutDoc, scale }).result as string || "";
             };
             divKeys.map((prop: string) => {
-                const p = (this.props as any)[prop] as string;
-                p && (style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer));
+                const p = (this.props as any)[prop];
+                typeof p === "string" && (style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer));
             });
             return style;
         }
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 9102b9fa4..ebd453295 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -65,6 +65,7 @@ export function testDocProps(toBeDetermined: any): toBeDetermined is DocumentVie
 // 
 export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string): any {
     const docProps = testDocProps(props) ? props : undefined;
+    const fieldKey = (props as any)?.fieldKey ? (props as any).fieldKey + "-" : "";
     const selected = property.includes(":selected");
     const isCaption = property.includes(":caption");
     const isAnchor = property.includes(":anchor");
@@ -99,7 +100,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
         case StyleProp.BackgroundColor: {
             if (isCaption) return "rgba(0,0,0 ,0.4)";
             if (Doc.UserDoc().renderStyle === "comic") return "transparent";
-            let docColor: Opt<string> = StrCast(doc?._backgroundColor);
+            let docColor: Opt<string> = StrCast(doc?.[fieldKey + "backgroundColor"], StrCast(doc?._backgroundColor));
             if (MainView.Instance.LastButton === doc) return darkScheme() ? "dimgrey" : "lightgrey";
             switch (doc?.type) {
                 case DocumentType.PRESELEMENT: docColor = docColor || (darkScheme() ? "" : ""); break;
diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx
index b2ae441d6..9a3183d88 100644
--- a/src/client/views/collections/CollectionCarousel3DView.tsx
+++ b/src/client/views/collections/CollectionCarousel3DView.tsx
@@ -104,27 +104,6 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume
         }, 1500);
     }
 
-    _downX = 0;
-    _downY = 0;
-    onPointerDown = (e: React.PointerEvent) => {
-        this._downX = e.clientX;
-        this._downY = e.clientY;
-        document.addEventListener("pointerup", this.onpointerup);
-    }
-    private _lastTap: number = 0;
-    private _doubleTap = false;
-    onpointerup = (e: PointerEvent) => {
-        this._doubleTap = (Date.now() - this._lastTap < 300 && e.button === 0 && Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2);
-        this._lastTap = Date.now();
-    }
-
-    onClick = (e: React.MouseEvent) => {
-        if (this._doubleTap) {
-            e.stopPropagation();
-            this.props.Document.isLightboxOpen = true;
-        }
-    }
-
     @computed get buttons() {
         if (!this.props.isContentActive()) return null;
         return <div className="arrow-buttons" >
@@ -167,7 +146,7 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume
         const index = NumCast(this.layoutDoc._itemIndex);
         const translateX = this.panelWidth() * (1 - index);
 
-        return <div className="collectionCarousel3DView-outer" onClick={this.onClick} onPointerDown={this.onPointerDown} ref={this.createDashEventsTarget}>
+        return <div className="collectionCarousel3DView-outer" ref={this.createDashEventsTarget}>
             <div className="carousel-wrapper" style={{ transform: `translateX(${translateX}px)` }}>
                 {this.content}
             </div>
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index cc90b9134..0642a1f9b 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -62,53 +62,37 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
                 </div>
                 <div className="collectionCarouselView-caption" key="caption"
                     style={{
-                        background: StrCast(this.layoutDoc._captionBackgroundColor, this.props.styleProvider?.(this.props.Document, this.props, StyleProp.BackgroundColor)),
-                        color: StrCast(this.layoutDoc._captionColor, StrCast(this.layoutDoc.color)),
-                        borderRadius: StrCast(this.layoutDoc._captionBorderRounding),
+                        background: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor + ":caption"),
+                        color: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color + ":caption"),
+                        borderRadius: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BorderRounding + ":caption"),
                     }}>
                     <FormattedTextBox key={index} {...this.props}
-                        xMargin={NumCast(this.layoutDoc["_carousel-caption-xMargin"])}
-                        yMargin={NumCast(this.layoutDoc["_carousel-caption-yMargin"])}
-                        Document={curDoc.layout} DataDoc={undefined} fieldKey={"caption"} />
+                        Document={curDoc.layout} DataDoc={undefined} fieldKey={"caption"}
+                        fontSize={NumCast(this.layoutDoc["caption-fontSize"])}
+                        xMargin={NumCast(this.layoutDoc["caption-xMargin"])}
+                        yMargin={NumCast(this.layoutDoc["caption-yMargin"])} />
                 </div>
             </>;
     }
     @computed get buttons() {
         return <>
-            <div key="back" className="carouselView-back" style={{ background: `${StrCast(this.props.Document.backgroundColor)}` }} onClick={this.goback}>
+            <div key="back" className="carouselView-back" style={{ background: `${StrCast(this.layoutDoc.backgroundColor)}` }} onClick={this.goback}>
                 <FontAwesomeIcon icon={"caret-left"} size={"2x"} />
             </div>
-            <div key="fwd" className="carouselView-fwd" style={{ background: `${StrCast(this.props.Document.backgroundColor)}` }} onClick={this.advance}>
+            <div key="fwd" className="carouselView-fwd" style={{ background: `${StrCast(this.layoutDoc.backgroundColor)}` }} onClick={this.advance}>
                 <FontAwesomeIcon icon={"caret-right"} size={"2x"} />
             </div>
         </>;
     }
 
-    _downX = 0;
-    _downY = 0;
-    onPointerDown = (e: React.PointerEvent) => {
-        this._downX = e.clientX;
-        this._downY = e.clientY;
-        document.addEventListener("pointerup", this.onpointerup);
-    }
-    private _lastTap: number = 0;
-    private _doubleTap = false;
-    onpointerup = (e: PointerEvent) => {
-        this._doubleTap = (Date.now() - this._lastTap < 300 && e.button === 0 && Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2);
-        this._lastTap = Date.now();
-    }
-
-    onClick = (e: React.MouseEvent) => {
-        if (this._doubleTap) {
-            e.stopPropagation();
-            this.props.Document.isLightboxOpen = true;
-        }
-    }
-
     render() {
-        return <div className="collectionCarouselView-outer" onClick={this.onClick} onPointerDown={this.onPointerDown} ref={this.createDashEventsTarget}>
+        return <div className="collectionCarouselView-outer" ref={this.createDashEventsTarget}
+            style={{
+                background: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor),
+                color: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color),
+            }}>
             {this.content}
-            {!this.props.Document._chromeHidden ? (null) : this.buttons}
+            {this.props.Document._chromeHidden ? (null) : this.buttons}
         </div>;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss
index 9eac75f4b..dc5231a3a 100644
--- a/src/client/views/collections/CollectionMenu.scss
+++ b/src/client/views/collections/CollectionMenu.scss
@@ -300,7 +300,7 @@
         .collection3DCarouselViewChrome-scrollSpeed-cont {
             justify-self: right;
             align-items: center;
-            display: grid;
+            display: flex;
             grid-auto-columns: auto;
             font-size: 75%;
             letter-spacing: 2px;
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index a26953ff6..95b0ef790 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -37,6 +37,7 @@ import { LightboxView } from "../LightboxView";
 import { Docs } from "../../documents/Documents";
 import { DocumentManager } from "../../util/DocumentManager";
 import { CollectionDockingView } from "./CollectionDockingView";
+import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox";
 
 @observer
 export class CollectionMenu extends AntimodeMenu<AntimodeMenuProps> {
@@ -260,6 +261,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
             case CollectionViewType.Schema: return (<CollectionSchemaViewChrome key="collchrome" {...this.props} />);
             case CollectionViewType.Tree: return (<CollectionTreeViewChrome key="collchrome" {...this.props} />);
             case CollectionViewType.Masonry: return (<CollectionStackingViewChrome key="collchrome" {...this.props} />);
+            case CollectionViewType.Carousel:
             case CollectionViewType.Carousel3D: return (<Collection3DCarouselViewChrome key="collchrome" {...this.props} />);
             case CollectionViewType.Grid: return (<CollectionGridViewChrome key="collchrome" {...this.props} />);
             case CollectionViewType.Docking: return (<CollectionDockingChrome key="collchrome" {...this.props} />);
@@ -1021,6 +1023,7 @@ export class Collection3DCarouselViewChrome extends React.Component<CollectionMe
         return (
             <div className="collection3DCarouselViewChrome-cont">
                 <div className="collection3DCarouselViewChrome-scrollSpeed-cont">
+                    {FormattedTextBox.Focused ? <RichTextMenu /> : (null)}
                     <div className="collectionStackingViewChrome-scrollSpeed-label">
                         AUTOSCROLL SPEED:
                     </div>
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index f6aecbb14..4417038fa 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -92,7 +92,8 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                 };
                 tab.element[0].style.borderTopRightRadius = "8px";
                 tab.element[0].children[1].appendChild(toggle);
-                tab._disposers.layerDisposer = reaction(() => ({ layer: tab.DashDoc.activeLayer, color: this.tabColor }),
+                tab._disposers.layerDisposer = reaction(() =>
+                    ({ layer: tab.DashDoc.activeLayer, color: this.tabColor }),
                     ({ layer, color }) => toggle.style.background = !layer ? color : "dimgrey", { fireImmediately: true });
             }
             // shifts the focus to this tab when another tab is dragged over it
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 8a6946b78..1ab367395 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -102,8 +102,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
                 const targetDoc = layoutDoc[DataSym];
                 if (targetDoc[targetField] instanceof ImageField) {
                     this.dataDoc[this.fieldKey] = ObjectField.MakeCopy(targetDoc[targetField] as ImageField);
-                    Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(targetDoc));
-                    Doc.SetNativeWidth(this.dataDoc, Doc.NativeHeight(targetDoc));
+                    Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(targetDoc), this.fieldKey);
+                    Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(targetDoc), this.fieldKey);
                     e.stopPropagation();
                 }
             }
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index c2860af76..9203207d7 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1,6 +1,6 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { isEqual } from "lodash";
-import { action, computed, IReactionDisposer, reaction, runInAction } from "mobx";
+import { action, computed, IReactionDisposer, reaction, runInAction, observable } from "mobx";
 import { observer } from "mobx-react";
 import { baseKeymap, selectAll } from "prosemirror-commands";
 import { history } from "prosemirror-history";
@@ -1132,6 +1132,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     }
 
     componentWillUnmount() {
+        FormattedTextBox.Focused === this && (FormattedTextBox.Focused = undefined);
         Object.values(this._disposers).forEach(disposer => disposer?.());
         this.endUndoTypingBatch();
         this.unhighlightSearchTerms();
@@ -1236,8 +1237,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     @action
     onFocused = (e: React.FocusEvent): void => {
         //applyDevTools.applyDevTools(this._editorView);
+        FormattedTextBox.Focused = this;
         this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props);
     }
+    @observable public static Focused: FormattedTextBox | undefined;
 
     onClick = (e: React.MouseEvent): void => {
         if (Math.abs(e.clientX - this._downX) > 4 || Math.abs(e.clientY - this._downY) > 4) {
@@ -1340,6 +1343,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         return wasUndoing;
     }
     onBlur = (e: any) => {
+        FormattedTextBox.Focused === this && (FormattedTextBox.Focused = undefined);
         if (RichTextMenu.Instance?.view === this._editorView && !this.props.isSelected(true)) {
             RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined);
         }
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 9faba9486..bd0ba3ad7 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -910,8 +910,8 @@ export namespace Doc {
     }
     export function NativeWidth(doc?: Doc, dataDoc?: Doc, useWidth?: boolean) { return !doc ? 0 : NumCast(doc._nativeWidth, NumCast((dataDoc || doc)[Doc.LayoutFieldKey(doc) + "-nativeWidth"], useWidth ? doc[WidthSym]() : 0)); }
     export function NativeHeight(doc?: Doc, dataDoc?: Doc, useHeight?: boolean) { return !doc ? 0 : NumCast(doc._nativeHeight, NumCast((dataDoc || doc)[Doc.LayoutFieldKey(doc) + "-nativeHeight"], useHeight ? doc[HeightSym]() : 0)); }
-    export function SetNativeWidth(doc: Doc, width: number | undefined) { doc[Doc.LayoutFieldKey(doc) + "-nativeWidth"] = width; }
-    export function SetNativeHeight(doc: Doc, height: number | undefined) { doc[Doc.LayoutFieldKey(doc) + "-nativeHeight"] = height; }
+    export function SetNativeWidth(doc: Doc, width: number | undefined, fieldKey?: string) { doc[(fieldKey ?? Doc.LayoutFieldKey(doc)) + "-nativeWidth"] = width; }
+    export function SetNativeHeight(doc: Doc, height: number | undefined, fieldKey?: string) { doc[(fieldKey ?? Doc.LayoutFieldKey(doc)) + "-nativeHeight"] = height; }
 
 
     const manager = new DocData();
-- 
cgit v1.2.3-70-g09d2


From 4334a553fdfdf44b1d1c609290fe2a874a408967 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 15 Apr 2021 00:04:18 -0400
Subject: fixed up carousels to work with templated documents

---
 .../views/collections/CollectionCarousel3DView.tsx | 40 +++++++++++++++++-----
 .../views/collections/CollectionCarouselView.tsx   | 32 +++++++++++++----
 src/client/views/collections/CollectionMenu.tsx    |  2 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |  1 +
 4 files changed, 59 insertions(+), 16 deletions(-)

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

diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx
index 9a3183d88..7cebabaa9 100644
--- a/src/client/views/collections/CollectionCarousel3DView.tsx
+++ b/src/client/views/collections/CollectionCarousel3DView.tsx
@@ -9,10 +9,11 @@ import { makeInterface } from '../../../fields/Schema';
 import { ScriptField } from '../../../fields/ScriptField';
 import { NumCast, ScriptCast, StrCast } from '../../../fields/Types';
 import { OmitKeys, returnFalse, Utils } from '../../../Utils';
-import { DragManager } from '../../util/DragManager';
+import { DragManager, dropActionType } from '../../util/DragManager';
 import { DocumentView } from '../nodes/DocumentView';
 import "./CollectionCarousel3DView.scss";
 import { CollectionSubView } from './CollectionSubView';
+import { StyleProp } from '../StyleProvider';
 
 type Carousel3DDocument = makeInterface<[typeof documentSchema, typeof collectionSchema]>;
 const Carousel3DDocument = makeInterface(documentSchema, collectionSchema);
@@ -42,17 +43,36 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume
         const displayDoc = (childPair: { layout: Doc, data: Doc }) => {
             const script = ScriptField.MakeScript("this._showCaption = 'caption'", { this: Doc.name });
             const onChildClick = script && (() => script);
-            return <DocumentView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
-                onDoubleClick={this.onChildDoubleClick}
-                onClick={onChildClick}
-                renderDepth={this.props.renderDepth + 1}
+            return <DocumentView
+                Document={childPair.layout}
+                DataDoc={childPair.layout.resolvedDataDoc as Doc}
+                styleProvider={this.props.styleProvider}
+                layerProvider={this.props.layerProvider}
+                docViewPath={this.props.docViewPath}
                 LayoutTemplate={this.props.childLayoutTemplate}
                 LayoutTemplateString={this.props.childLayoutString}
-                Document={childPair.layout}
-                DataDoc={childPair.data}
+                freezeDimensions={this.props.childFreezeDimensions}
+                renderDepth={this.props.renderDepth + 1}
                 PanelWidth={this.panelWidth}
                 PanelHeight={this.panelHeight}
+                rootSelected={this.rootSelected}
+                dropAction={StrCast(this.props.Document.childDropAction) as dropActionType}
                 ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+                focus={this.props.focus}
+                docFilters={this.docFilters}
+                onDoubleClick={this.onChildDoubleClick}
+                onClick={onChildClick}
+                isContentActive={returnFalse}
+                docRangeFilters={this.docRangeFilters}
+                searchFilterDocs={this.searchFilterDocs}
+                ContainingCollectionDoc={this.props.CollectionView?.props.Document}
+                ContainingCollectionView={this.props.CollectionView}
+                addDocument={this.props.addDocument}
+                moveDocument={this.props.moveDocument}
+                removeDocument={this.props.removeDocument}
+                whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
+                addDocTab={this.props.addDocTab}
+                pinToPres={this.props.pinToPres}
                 bringToFront={returnFalse}
             />;
         };
@@ -146,7 +166,11 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume
         const index = NumCast(this.layoutDoc._itemIndex);
         const translateX = this.panelWidth() * (1 - index);
 
-        return <div className="collectionCarousel3DView-outer" ref={this.createDashEventsTarget}>
+        return <div className="collectionCarousel3DView-outer" ref={this.createDashEventsTarget}
+            style={{
+                background: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor),
+                color: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color),
+            }}  >
             <div className="carousel-wrapper" style={{ transform: `translateX(${translateX}px)` }}>
                 {this.content}
             </div>
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 0642a1f9b..4a7bdf6db 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -7,7 +7,7 @@ import { collectionSchema, documentSchema } from '../../../fields/documentSchema
 import { makeInterface } from '../../../fields/Schema';
 import { NumCast, ScriptCast, StrCast } from '../../../fields/Types';
 import { OmitKeys, returnFalse } from '../../../Utils';
-import { DragManager } from '../../util/DragManager';
+import { DragManager, dropActionType } from '../../util/DragManager';
 import { DocumentView } from '../nodes/DocumentView';
 import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
 import { StyleProp } from '../StyleProvider';
@@ -47,16 +47,34 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument)
         return !(curDoc?.layout instanceof Doc) ? (null) :
             <>
                 <div className="collectionCarouselView-image" key="image">
-                    <DocumentView  {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit}
-                        onDoubleClick={this.onContentDoubleClick}
-                        onClick={this.onContentClick}
-                        renderDepth={this.props.renderDepth + 1}
+                    <DocumentView
+                        Document={curDoc.layout}
+                        DataDoc={curDoc.layout.resolvedDataDoc as Doc}
+                        styleProvider={this.props.styleProvider}
+                        layerProvider={this.props.layerProvider}
+                        docViewPath={this.props.docViewPath}
                         LayoutTemplate={this.props.childLayoutTemplate}
                         LayoutTemplateString={this.props.childLayoutString}
-                        Document={curDoc.layout}
-                        DataDoc={curDoc.data}
+                        freezeDimensions={this.props.childFreezeDimensions}
+                        renderDepth={this.props.renderDepth + 1}
+                        PanelWidth={this.props.PanelWidth}
                         PanelHeight={this.panelHeight}
+                        rootSelected={this.rootSelected}
+                        dropAction={StrCast(this.props.Document.childDropAction) as dropActionType}
                         ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+                        focus={this.props.focus}
+                        docFilters={this.docFilters}
+                        isContentActive={returnFalse}
+                        docRangeFilters={this.docRangeFilters}
+                        searchFilterDocs={this.searchFilterDocs}
+                        ContainingCollectionDoc={this.props.CollectionView?.props.Document}
+                        ContainingCollectionView={this.props.CollectionView}
+                        addDocument={this.props.addDocument}
+                        moveDocument={this.props.moveDocument}
+                        removeDocument={this.props.removeDocument}
+                        whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
+                        addDocTab={this.props.addDocTab}
+                        pinToPres={this.props.pinToPres}
                         bringToFront={returnFalse}
                     />
                 </div>
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 95b0ef790..ab4f197a6 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -554,7 +554,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
                         <div className="collectionMenu-divider" key="divider3"></div>
                         {this.lightboxButton}
                         {this.recordButton}
-                        {/* {!this._buttonizableCommands ? (null) : this.templateChrome} */}
+                        {!this._buttonizableCommands ? (null) : this.templateChrome}
                     </div>
                 </div>
             </div>
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 9203207d7..25dc93605 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1342,6 +1342,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         this._undoTyping = undefined;
         return wasUndoing;
     }
+    @action
     onBlur = (e: any) => {
         FormattedTextBox.Focused === this && (FormattedTextBox.Focused = undefined);
         if (RichTextMenu.Instance?.view === this._editorView && !this.props.isSelected(true)) {
-- 
cgit v1.2.3-70-g09d2

