From 2d8f763d763080fd52e940abb1a98b41e2da23fd Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 7 Sep 2022 14:28:44 -0400
Subject: fixed dragging stackedTimeline entries so that they appear during
 drag.   fixed cursors for video/pdf/stackedTimeline to be a little more
 clear.   fixed initial corner resize of pdfs.  fixed videobox marquee drag
 when viewScale is undefined.

---
 src/client/views/DocumentDecorations.tsx | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 3589e014a..a79f727a7 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -476,6 +476,9 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                 if (e.ctrlKey && !Doc.NativeHeight(docView.props.Document)) docView.toggleNativeDimensions();
                 if (dX !== 0 || dY !== 0 || dW !== 0 || dH !== 0) {
                     const doc = Document(docView.rootDoc);
+                    if (doc.nativeHeightUnfrozen && !NumCast(doc.nativeHeight)) {
+                        doc._nativeHeight = (NumCast(doc._height) / NumCast(doc._width, 1)) * docView.nativeWidth;
+                    }
                     const nwidth = docView.nativeWidth;
                     const nheight = docView.nativeHeight;
                     let docheight = doc._height || 0;
-- 
cgit v1.2.3-70-g09d2


From 4315a0378bc54ae9eaa684d416839f635c38e865 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 12 Sep 2022 16:18:42 -0400
Subject: fixed rotating UI for video boxes.  fixed generating error response
 for unsupported video/audio formats.

---
 src/client/views/DocumentDecorations.tsx |  8 +++----
 src/client/views/nodes/VideoBox.tsx      | 38 +++++++++++++++++++++-----------
 src/server/DashUploadUtils.ts            |  3 +++
 3 files changed, 31 insertions(+), 18 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index a79f727a7..832d0a35c 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -738,11 +738,9 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                                 </>
                             )}
 
-                            {useRotation && (
-                                <div key="rot" className={`documentDecorations-rotation`} onPointerDown={this.onRotateDown} onContextMenu={e => e.preventDefault()}>
-                                    {'⟲'}
-                                </div>
-                            )}
+                            <div key="rot" className={`documentDecorations-rotation`} onPointerDown={this.onRotateDown} onContextMenu={e => e.preventDefault()}>
+                                {'⟲'}
+                            </div>
 
                             {useRounding && (
                                 <div
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 5a3594ffc..b45ee7f6e 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -914,21 +914,33 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
 
     // renders video controls
     componentUI = (boundsLeft: number, boundsTop: number) => {
-        const bounds = this.props.docViewPath().lastElement().getBounds();
-        const left = bounds?.left || 0;
-        const right = bounds?.right || 0;
-        const top = bounds?.top || 0;
-        const height = (bounds?.bottom || 0) - top;
-        const width = Math.max(right - left, 100);
-        const uiHeight = Math.max(25, Math.min(50, height / 10));
-        const uiMargin = Math.min(10, height / 20);
-        const vidHeight = (height * this.heightPercent) / 100;
-        const yPos = top + vidHeight - uiHeight - uiMargin;
-        const xPos = uiHeight / vidHeight > 0.4 ? right + 10 : left + 10;
+        const xf = this.props.ScreenToLocalTransform().inverse();
+        const height = this.props.PanelHeight();
+        const vidHeight = (height * this.heightPercent) / 100 / this.scaling();
+        const vidWidth = this.props.PanelWidth() / this.scaling();
+        const uiHeight = 25;
+        const uiMargin = 10;
+        const yBot = xf.transformPoint(0, vidHeight)[1];
+        // prettier-ignore
+        const yMid =  (xf.transformPoint(0, 0)[1] +
+                       xf.transformPoint(0, height / this.scaling())[1]) /  2;
+        const xPos = xf.transformPoint(vidWidth / 2, 0)[0];
+        const xRight = xf.transformPoint(vidWidth, 0)[0];
         const opacity = this._scrubbing ? 0.3 : this._controlsVisible ? 1 : 0;
-        return this._fullScreen || right - left < 50 ? null : (
+        return this._fullScreen || (xRight - xPos) * 2 < 50 ? null : (
             <div className="videoBox-ui-wrapper" style={{ clip: `rect(${boundsTop}px, 10000px, 10000px, ${boundsLeft}px)` }}>
-                <div className="videoBox-ui" style={{ left: xPos, top: yPos, height: uiHeight, width: width - 20, transition: this._clicking ? 'top 0.5s' : '', opacity: opacity }}>
+                <div
+                    className="videoBox-ui"
+                    style={{
+                        transformOrigin: 'top left',
+                        transform: `rotate(${NumCast(this.rootDoc.jitterRotation)}deg) translate(${-(xRight - xPos) + 10}px, ${yBot - yMid - uiHeight - uiMargin}px)`,
+                        left: xPos,
+                        top: yMid,
+                        height: uiHeight,
+                        width: (xRight - xPos) * 2 - 20,
+                        transition: this._clicking ? 'top 0.5s' : '',
+                        opacity,
+                    }}>
                     {this.UIButtons}
                 </div>
             </div>
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index e94ef8534..8cf657da4 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -142,6 +142,7 @@ export namespace DashUploadUtils {
                     const result = await UploadImage(path, basename(path));
                     return { source: file, result };
                 }
+                return { source: file, result: { name: 'Unsupported image format', message: `Could not upload unsupported file (${name}). Please convert to an .jpg` } };
             case 'video':
                 if (format.includes('x-matroska')) {
                     console.log('case video');
@@ -179,6 +180,7 @@ export namespace DashUploadUtils {
                 if (videoFormats.includes(format)) {
                     return MoveParsedFile(file, Directory.videos);
                 }
+                return { source: file, result: { name: 'Unsupported video format', message: `Could not upload unsupported file (${name}). Please convert to an .mp4` } };
             case 'application':
                 if (applicationFormats.includes(format)) {
                     return UploadPdf(file);
@@ -191,6 +193,7 @@ export namespace DashUploadUtils {
                 if (audioFormats.includes(format)) {
                     return UploadAudio(file, format);
                 }
+                return { source: file, result: { name: 'Unsupported audio format', message: `Could not upload unsupported file (${name}). Please convert to an .mp3` } };
             case 'text':
                 if (types[1] == 'csv') {
                     return UploadCsv(file);
-- 
cgit v1.2.3-70-g09d2


From 65026fdb919132f6046b45fc3b0490df2e5ad2fe Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 14 Sep 2022 11:12:29 -0400
Subject: changed docking view thumbnails to be imagefields, not docs.  allowed
 docking view to be nested to avoid crashes before when they became nested.  
 fixed dropping docs with dropAction of 'alias' to never remove them.  fixed
 clearing startLink to not deselect when link is already started

---
 src/client/util/SelectionManager.ts                |  2 +-
 src/client/views/DashboardView.tsx                 |  4 +--
 src/client/views/DocumentDecorations.tsx           |  2 +-
 .../views/collections/CollectionDockingView.tsx    | 32 ++++++++++++++++------
 src/client/views/collections/CollectionSubView.tsx |  2 +-
 src/client/views/collections/CollectionView.tsx    |  1 +
 src/client/views/collections/TabDocView.tsx        |  2 +-
 src/client/views/nodes/DocumentLinksButton.tsx     |  4 +--
 src/client/views/nodes/LinkDocPreview.tsx          |  2 +-
 src/client/views/topbar/TopBar.tsx                 |  4 +--
 10 files changed, 36 insertions(+), 19 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 7a555d5f8..a3d6f5227 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -91,7 +91,7 @@ export namespace SelectionManager {
     }
 
     export function Views(): Array<DocumentView> {
-        return Array.from(manager.SelectedViews.keys()).filter(dv => manager.SelectedViews.get(dv)?._viewType !== CollectionViewType.Docking);
+        return Array.from(manager.SelectedViews.keys()); //.filter(dv => manager.SelectedViews.get(dv)?._viewType !== CollectionViewType.Docking);
     }
     export function SelectedSchemaDoc(): Doc | undefined {
         return manager.SelectedSchemaDocument;
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index 6415601f1..12fc3133d 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -50,7 +50,7 @@ export class DashboardView extends React.Component {
         this.selectedDashboardGroup = group;
     };
 
-    clickDashboard = async (e: React.MouseEvent, dashboard: Doc) => {
+    clickDashboard = (e: React.MouseEvent, dashboard: Doc) => {
         if (e.detail === 2) {
             Doc.AddDocToList(Doc.MySharedDocs, 'viewed', dashboard);
             Doc.ActiveDashboard = dashboard;
@@ -156,7 +156,7 @@ export class DashboardView extends React.Component {
                     </div>
                     <div className="all-dashboards">
                         {this.getDashboards().map(dashboard => {
-                            const href = ImageCast((dashboard.thumb as Doc)?.data)?.url.href;
+                            const href = ImageCast(dashboard.thumb)?.url.href;
                             return (
                                 <div
                                     className="dashboard-container"
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 832d0a35c..0fc33bdea 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -189,7 +189,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
     onCloseClick = (forceDeleteOrIconify: boolean | undefined) => {
         const views = SelectionManager.Views()
             .slice()
-            .filter(v => v);
+            .filter(v => v && v.props.renderDepth > 0);
         if (forceDeleteOrIconify === false && this._iconifyBatch) return;
         this._deleteAfterIconify = forceDeleteOrIconify || this._iconifyBatch ? true : false;
         if (!this._iconifyBatch) {
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 10b54edad..31c839af7 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -6,7 +6,7 @@ import { Doc, DocListCast, Opt } from '../../../fields/Doc';
 import { Id } from '../../../fields/FieldSymbols';
 import { InkTool } from '../../../fields/InkField';
 import { List } from '../../../fields/List';
-import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types';
 import { ImageField } from '../../../fields/URLField';
 import { inheritParentAcls } from '../../../fields/util';
 import { emptyFunction, incrementTitleCopy } from '../../../Utils';
@@ -56,7 +56,7 @@ export class CollectionDockingView extends CollectionSubView() {
 
     constructor(props: SubCollectionViewProps) {
         super(props);
-        runInAction(() => (CollectionDockingView.Instance = this));
+        if (this.props.renderDepth < 0) runInAction(() => (CollectionDockingView.Instance = this));
         //Why is this here?
         (window as any).React = React;
         (window as any).ReactDOM = ReactDOM;
@@ -73,7 +73,7 @@ export class CollectionDockingView extends CollectionSubView() {
     public StartOtherDrag = (e: { pageX: number; pageY: number }, dragDocs: Doc[], finishDrag?: (aborted: boolean) => void) => {
         this._flush = this._flush ?? UndoManager.StartBatch('golden layout drag');
         const config = dragDocs.length === 1 ? CollectionDockingView.makeDocumentConfig(dragDocs[0]) : { type: 'row', content: dragDocs.map(doc => CollectionDockingView.makeDocumentConfig(doc)) };
-        const dragSource = this._goldenLayout.createDragSource(document.createElement('div'), config);
+        const dragSource = CollectionDockingView.Instance?._goldenLayout.createDragSource(document.createElement('div'), config);
         this.tabDragStart(dragSource, finishDrag);
         dragSource._dragListener.onMouseDown({ pageX: e.pageX, pageY: e.pageY, preventDefault: emptyFunction, button: 0 });
     };
@@ -395,10 +395,10 @@ export class CollectionDockingView extends CollectionSubView() {
             const _height = Number(getComputedStyle(content).height.replace('px', ''));
             return CollectionFreeFormView.UpdateIcon(this.layoutDoc[Id] + '-icon' + new Date().getTime(), content, _width, _height, _width, _height, 0, 1, true, this.layoutDoc[Id] + '-icon', (iconFile, _nativeWidth, _nativeHeight) => {
                 const img = Docs.Create.ImageDocument(new ImageField(iconFile), { title: this.rootDoc.title + '-icon', _width, _height, _nativeWidth, _nativeHeight });
-                const proto = Cast(img.proto, Doc, null)!;
-                proto['data-nativeWidth'] = _width;
-                proto['data-nativeHeight'] = _height;
-                this.dataDoc.thumb = img;
+                const proto = this.dataDoc; // Cast(img.proto, Doc, null)!;
+                proto['thumb-nativeWidth'] = _width;
+                proto['thumb-nativeHeight'] = _height;
+                this.dataDoc.thumb = new ImageField(iconFile);
             });
         }
     }
@@ -532,7 +532,23 @@ export class CollectionDockingView extends CollectionSubView() {
     };
 
     render() {
-        return <div className="collectiondockingview-container" onPointerDown={this.onPointerDown} ref={this._containerRef} />;
+        const href = ImageCast(this.rootDoc.thumb)?.url.href;
+        return this.props.renderDepth > -1 ? (
+            <div>
+                {href ? (
+                    <img
+                        style={{ background: 'white', top: 0, position: 'absolute' }}
+                        src={href} // + '?d=' + (new Date()).getTime()}
+                        width={this.props.PanelWidth()}
+                        height={this.props.PanelHeight()}
+                    />
+                ) : (
+                    <p>nested dashboards has no thumbnail</p>
+                )}
+            </div>
+        ) : (
+            <div className="collectiondockingview-container" onPointerDown={this.onPointerDown} ref={this._containerRef} />
+        );
     }
 }
 
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 4227955ef..7fc1a800b 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -212,7 +212,7 @@ export function CollectionSubView<X>(moreProps?: X) {
                 let added = false;
                 const dropAction = docDragData.dropAction || docDragData.userDropAction;
                 const targetDocments = DocListCast(this.dataDoc[this.props.fieldKey]);
-                const someMoved = !docDragData.userDropAction && docDragData.draggedDocuments.some(drag => targetDocments.includes(drag));
+                const someMoved = !dropAction && docDragData.draggedDocuments.some(drag => targetDocments.includes(drag));
                 if (someMoved) docDragData.droppedDocuments = docDragData.droppedDocuments.map((drop, i) => (targetDocments.includes(docDragData.draggedDocuments[i]) ? docDragData.draggedDocuments[i] : drop));
                 if ((!dropAction || dropAction === 'same' || dropAction === 'move' || someMoved) && docDragData.moveDocument) {
                     const movedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] === d);
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 1ee77d4ce..0a06b6e00 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -116,6 +116,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
         switch (type) {
             default:
             case CollectionViewType.Freeform: return <CollectionFreeFormView key="collview" {...props} />;
+            case CollectionViewType.Docking: return <CollectionDockingView key="collview" {...props} />;
             case CollectionViewType.Schema: return <CollectionSchemaView key="collview" {...props} />;
             case CollectionViewType.Docking: return <CollectionDockingView key="collview" {...props} />;
             case CollectionViewType.Tree: return <CollectionTreeView key="collview" {...props} />;
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 46386fa71..b9262763f 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -400,7 +400,7 @@ export class TabDocView extends React.Component<TabDocViewProps> {
     hideMinimap = () => this.disableMinimap() || BoolCast(this._document?.hideMinimap);
 
     @computed get docView() {
-        return !this._activated || !this._document || this._document._viewType === CollectionViewType.Docking ? null : (
+        return !this._activated || !this._document ? null : (
             <>
                 <DocumentView
                     key={this._document[Id]}
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index a37de7f69..9ffbf8e37 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -5,7 +5,7 @@ import { observer } from 'mobx-react';
 import { Doc, Opt } from '../../../fields/Doc';
 import { StrCast } from '../../../fields/Types';
 import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../Utils';
+import { emptyFunction, returnFalse, setupMoveUpEvents, StopEvent } from '../../../Utils';
 import { DocUtils } from '../../documents/Documents';
 import { DragManager } from '../../util/DragManager';
 import { Hypothesis } from '../../util/HypothesisUtils';
@@ -287,7 +287,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
                     </div>
                 ) : null}
                 {this.props.InMenu && this.props.StartLink ? ( //if link has been started from current node, then set behavior of link button to deactivate linking when clicked again
-                    <div className={`documentLinksButton ${isActive ? `startLink` : ``}`} ref={this._linkButton} onPointerDown={isActive ? undefined : this.onLinkButtonDown} onClick={isActive ? this.clearLinks : this.onLinkClick}>
+                    <div className={`documentLinksButton ${isActive ? `startLink` : ``}`} ref={this._linkButton} onPointerDown={isActive ? StopEvent : this.onLinkButtonDown} onClick={isActive ? this.clearLinks : this.onLinkClick}>
                         <FontAwesomeIcon className="documentdecorations-icon" icon="link" />
                     </div>
                 ) : null}
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 93ca22d5d..f50524e4e 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -249,7 +249,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
                             searchFilterDocs={returnEmptyDoclist}
                             ContainingCollectionDoc={undefined}
                             ContainingCollectionView={undefined}
-                            renderDepth={-1}
+                            renderDepth={0}
                             suppressSetHeight={true}
                             PanelWidth={this.width}
                             PanelHeight={this.height}
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index cbcfed06f..096b2561f 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -28,12 +28,12 @@ import { ReportManager } from '../../util/ReportManager';
 @observer
 export class TopBar extends React.Component {
     navigateToHome = () => {
-        CollectionDockingView.Instance?.CaptureThumbnail()?.then(() => {
+        (CollectionDockingView.Instance?.CaptureThumbnail() ?? new Promise<void>(res => res())).then(() => {
             Doc.ActivePage = 'home';
             DashboardView.closeActiveDashboard(); // bcz: if we do this, we need some other way to keep track, for user convenience, of the last dashboard in use
         });
     };
-    
+
     render() {
         const activeDashboard = Doc.ActiveDashboard;
         return (
-- 
cgit v1.2.3-70-g09d2


From 37be2477782b0b372c16d46df3f9634ebf3677fe Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Wed, 21 Sep 2022 01:43:03 -0400
Subject: restyled document decorations

and changed novice mode to exclude `data` in treeView
---
 src/client/views/DocumentButtonBar.tsx             |   2 +-
 src/client/views/DocumentDecorations.scss          | 189 ++++++++++++++-------
 src/client/views/DocumentDecorations.tsx           |  13 +-
 src/client/views/_nodeModuleOverrides.scss         |   4 +-
 .../views/collections/CollectionDockingView.scss   |   8 +
 .../views/collections/CollectionTreeView.scss      |   1 +
 src/client/views/collections/TabDocView.tsx        |   4 +-
 src/client/views/collections/TreeView.scss         |  20 ++-
 src/client/views/collections/TreeView.tsx          |   4 +-
 src/client/views/global/globalCssVariables.scss    |   4 +
 src/client/views/nodes/button/FontIconBox.tsx      |   2 +-
 src/client/views/nodes/trails/PresBox.tsx          |  16 +-
 src/client/views/topbar/TopBar.tsx                 |   2 +-
 13 files changed, 178 insertions(+), 91 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 35c0b9a7d..0bfe6e87a 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -434,7 +434,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
                         <DocumentLinksButton View={this.view0} AlwaysOn={true} InMenu={true} StartLink={false} />
                     </div>
                 ) : null}
-                <div className="documentButtonBar-button">{this.recordButton}</div>
+                {Doc.noviceMode ? null : <div className="documentButtonBar-button">{this.recordButton}</div>}
                 {
                     Doc.noviceMode ? null : <div className="documentButtonBar-button">{this.templateButton}</div>
                     /*<div className="documentButtonBar-button">
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index b490278c3..2e8d31478 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -22,6 +22,129 @@ $resizeHandler: 8px;
     grid-template-columns: $resizeHandler 1fr $resizeHandler;
     pointer-events: none;
 
+    .documentDecorations-topbar {
+        display: flex;
+        grid-column-start: 1;
+        grid-column-end: 4;
+        flex-direction: row;
+        gap: 2px;
+
+
+        .documentDecorations-openButton {
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            background: #3ce312;
+            border: solid 1.5px #0a620a;
+            color: #3ce312;
+            transition: 0.1s ease;
+            font-size: 11px;
+            opacity: 1;
+            pointer-events: all;
+            width: 20px;
+            height: 20px;
+            min-width: 20px;
+            border-radius: 100%;
+            cursor: pointer;
+
+            &:hover {
+                color: #02600d;
+            }
+        }
+        
+        .documentDecorations-closeButton {
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            background: #fb9d75;
+            border: solid 1.5px #a94442;
+            color: #fb9d75;
+            transition: 0.1s ease;
+            opacity: 1;
+            pointer-events: all;
+            width: 20px;
+            height: 20px;
+            min-width: 20px;
+            border-radius: 100%;
+            cursor: pointer;
+
+            &:hover {
+                color: #a94442;
+            }
+        
+            > svg {
+                margin: 0;
+            }
+        }
+
+        .documentDecorations-minimizeButton {
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            background: #ffdd00;
+            border: solid 1.5px #a94442;
+            color: #ffdd00;
+            transition: 0.1s ease;
+            font-size: 11px;
+            opacity: 1;
+            grid-column: 2;
+            pointer-events: all;
+            width: 20px;
+            height: 20px;
+            min-width: 20px;
+            border-radius: 100%;
+            cursor: pointer;
+
+            &:hover {
+                color: #a94442;
+            }
+        
+            > svg {
+                margin: 0;
+            }
+        }
+
+        .documentDecorations-title-Dark,
+        .documentDecorations-title {
+            opacity: 1;
+            width: calc(100% - 60px); // = margin-left + margin-right
+            grid-column: 3;
+            pointer-events: auto;
+            overflow: hidden;
+            text-align: center;
+            display: flex;
+            height: 20px;
+            border-radius: 8px;
+            outline: none;
+            border: none;
+
+            .documentDecorations-titleSpan,
+            .documentDecorations-titleSpan-Dark {
+                width: 100%;
+                border-radius: 8px;
+                background: $light-gray;
+                display: inline-block;
+                cursor: move;
+            }
+            .documentDecorations-titleSpan-Dark {
+                background: hsla(0, 0%, 0%, 0.412);
+            }
+        }
+
+        .documentDecorations-title-Dark {
+            color: white;
+            background: black;
+        }
+
+        .documentDecorations-titleBackground {
+            background: $light-gray;
+            border-radius: 8px;
+            width: 100%;
+            height: 100%;
+            position: absolute;
+        }
+    }
+
     .documentDecorations-centerCont {
         grid-column: 2;
         background: none;
@@ -225,76 +348,12 @@ $resizeHandler: 8px;
         cursor: ew-resize;
     }
 
-    .documentDecorations-title-Dark,
-    .documentDecorations-title {
-        opacity: 1;
-        width: calc(100% - 8px); // = margin-left + margin-right
-        grid-column: 2;
-        grid-column-end: 2;
-        pointer-events: auto;
-        overflow: hidden;
-        text-align: center;
-        display: flex;
-        margin-left: 6px; // closeButton width (14) - leftColumn width (8)
-        margin-right: 2px;
-        height: 20px;
-        position: absolute;
-        border-radius: 8px;
-        background: rgba(159, 159, 159, 0.1);
-
-        .documentDecorations-titleSpan,
-        .documentDecorations-titleSpan-Dark {
-            width: 100%;
-            border-radius: 8px;
-            background: #ffffffa0;
-            position: absolute;
-            display: inline-block;
-            cursor: move;
-        }
-        .documentDecorations-titleSpan-Dark {
-            background: hsla(0, 0%, 0%, 0.412);
-        }
-    }
-    .documentDecorations-title-Dark {
-        color: white;
-        background: black;
-    }
-
-    .documentDecorations-titleBackground {
-        background: #ffffffcf;
-        border-radius: 8px;
-        width: 100%;
-        height: 100%;
-        position: absolute;
-    }
-
     .focus-visible {
         margin-left: 0px;
     }
 }
 
-.documentDecorations-openButton {
-    display: flex;
-    align-items: center;
-    opacity: 1;
-    grid-column-start: 3;
-    pointer-events: all;
-    cursor: pointer;
-}
 
-.documentDecorations-closeButton {
-    display: flex;
-    align-items: center;
-    opacity: 1;
-    grid-column: 1;
-    pointer-events: all;
-    width: 14px;
-    cursor: pointer;
-
-    > svg {
-        margin: 0;
-    }
-}
 
 .documentDecorations-background {
     background: lightblue;
@@ -329,7 +388,7 @@ $resizeHandler: 8px;
     justify-content: center;
     align-items: center;
     gap: 5px;
-    background: $medium-gray;
+    background: $light-gray;
 }
 
 .linkButtonWrapper {
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 0fc33bdea..95025bf70 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -719,9 +719,12 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                                 width: bounds.r - bounds.x + this._resizeBorderWidth + 'px',
                                 height: bounds.b - bounds.y + this._resizeBorderWidth + this._titleHeight + 'px',
                             }}>
-                            {hideDeleteButton ? <div /> : topBtn('close', this.hasIcons ? 'times' : 'window-maximize', undefined, e => this.onCloseClick(this.hasIcons ? true : undefined), 'Close')}
-                            {titleArea}
-                            {hideOpenButton ? null : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Tab (ctrl: as alias, shift: in new collection)')}
+                            <div className="documentDecorations-topbar">
+                                {hideDeleteButton ? <div /> : topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')}
+                                {hideDeleteButton ? <div /> : topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')}
+                                {titleArea}
+                                {hideOpenButton ? null : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Tab (ctrl: as alias, shift: in new collection)')}
+                            </div>
                             {hideResizers ? null : (
                                 <>
                                     <div key="tl" className={`documentDecorations-topLeftResizer ${resizerScheme}`} onPointerDown={this.onPointerDown} onContextMenu={e => e.preventDefault()} />
@@ -738,9 +741,9 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                                 </>
                             )}
 
-                            <div key="rot" className={`documentDecorations-rotation`} onPointerDown={this.onRotateDown} onContextMenu={e => e.preventDefault()}>
+                            {!Doc.noviceMode && <div key="rot" className={`documentDecorations-rotation`} onPointerDown={this.onRotateDown} onContextMenu={e => e.preventDefault()}>
                                 {'⟲'}
-                            </div>
+                            </div>}
 
                             {useRounding && (
                                 <div
diff --git a/src/client/views/_nodeModuleOverrides.scss b/src/client/views/_nodeModuleOverrides.scss
index b1cce8705..c99281323 100644
--- a/src/client/views/_nodeModuleOverrides.scss
+++ b/src/client/views/_nodeModuleOverrides.scss
@@ -44,8 +44,8 @@ div .lm_header {
     position: absolute;
     width: calc(100% - 60px);
     overflow: scroll;
-    background: #6b6b6b6b; //$dark-gray;
-    border-radius: 5px;
+    background: transparent; //$dark-gray;
+    border-radius: 0px;
 }
 
 .lm_tab {
diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index 091ba8e74..ac3541f2c 100644
--- a/src/client/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -154,7 +154,15 @@
         background: $white;
     }
 
+    .lm_controls {
+        height: 27px;
+        display: flex;
+        align-content: center;
+        justify-content: center;
+    }
+
     .lm_controls > li {
+        height: 27px !important;
         opacity: 1;
         transform: scale(1);
     }
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index c0561e42c..a182a72c5 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -104,6 +104,7 @@
     text-overflow: ellipsis;
     white-space: pre-wrap;
     min-width: 10px;
+    grid-column: 2;
 }
 .docContainer-system {
     font-variant: all-small-caps;
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index a82bd2dc8..98121f423 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -56,7 +56,9 @@ export class TabDocView extends React.Component<TabDocViewProps> {
         return this._document && Doc.Layout(this._document);
     }
     @computed get tabColor() {
-        return StrCast(this._document?._backgroundColor, StrCast(this._document?.backgroundColor, DefaultStyleProvider(this._document, undefined, StyleProp.BackgroundColor)));
+        let tabColor = StrCast(this._document?._backgroundColor, StrCast(this._document?.backgroundColor, DefaultStyleProvider(this._document, undefined, StyleProp.BackgroundColor)));
+        if (tabColor === 'transparent') return 'black';
+        return tabColor;
     }
     @computed get tabTextColor() {
         return this._document?.type === DocumentType.PRES ? 'black' : StrCast(this._document?._color, StrCast(this._document?.color, DefaultStyleProvider(this._document, undefined, StyleProp.Color)));
diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss
index ce87e6f89..cfb97709b 100644
--- a/src/client/views/collections/TreeView.scss
+++ b/src/client/views/collections/TreeView.scss
@@ -53,13 +53,16 @@
     }
 
     .bullet {
+        grid-column: 1;
+        display: flex;
+        justify-content: center;
+        align-items: center;
         position: relative;
         width: $TREE_BULLET_WIDTH;
+        min-height: 20px;
         color: $medium-gray;
-        margin-top: 3px;
-        // transform: scale(1.3, 1.3); // bcz: why was this here?  It makes displaying images in the treeView for documents that have icons harder.
         border: #80808030 1px solid;
-        border-radius: 4px;
+        border-radius: 5px;
     }
 }
 
@@ -113,7 +116,15 @@
 .treeView-header-editing,
 .treeView-header {
     border: transparent 1px solid;
-    display: flex;
+    display: grid;
+    align-items: center;
+    grid-auto-columns: 22px auto 22px;
+    width: 100%;
+    border-radius: 5px;
+
+    &:hover {
+        background-color: #bdddf5;
+    }
 
     //align-items: center;
     ::-webkit-scrollbar {
@@ -140,6 +151,7 @@
 
     .treeView-rightButtons {
         display: flex;
+        grid-column: 3;
         align-items: center;
         margin-left: 0.25rem;
         opacity: 0.75;
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 833e364b3..b489b5214 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -736,7 +736,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                         }}
                     />
                 )}
-                {this.doc.treeViewExpandedViewLock || Doc.IsSystem(this.doc) ? null : (
+                {Doc.noviceMode ? null : this.doc.treeViewExpandedViewLock || Doc.IsSystem(this.doc) ? null : (
                     <span className="collectionTreeView-keyHeader" title="type of expanded data" key={this.treeViewExpandedView} onPointerDown={this.expandNextviewType}>
                         {this.treeViewExpandedView}
                     </span>
@@ -953,7 +953,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                 <div
                     className={`treeView-header` + (editing ? '-editing' : '')}
                     key="titleheader"
-                    style={{ width: StrCast(this.doc.treeViewHeaderWidth, 'max-content') }}
+                    style={{ width: '100%' }}
                     ref={this._header}
                     onClick={this.ignoreEvent}
                     onPointerDown={this.ignoreEvent}
diff --git a/src/client/views/global/globalCssVariables.scss b/src/client/views/global/globalCssVariables.scss
index 8a75aeef8..ac2c04aaa 100644
--- a/src/client/views/global/globalCssVariables.scss
+++ b/src/client/views/global/globalCssVariables.scss
@@ -7,6 +7,10 @@ $medium-gray: #9f9f9f;
 $dark-gray: #323232;
 $black: #000000;
 
+$close-red: red;
+$minimize-yellow: yellow;
+$open-green: green;
+
 $light-blue: #bdddf5;
 $light-blue-transparent: #bdddf590;
 $medium-blue: #4476f7;
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index 4a6099fb3..6d1751b25 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -275,7 +275,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
                     icon = 'globe-asia';
                     text = 'User Default';
                 }
-                noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking];
+                noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking, CollectionViewType.NoteTaking];
             } else if (script?.script.originalScript.startsWith('setFont')) {
                 const editorView = RichTextMenu.Instance?.TextView?.EditorView;
                 text = StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index ab59e6112..7f0f13437 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -2321,8 +2321,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
         const isMini: boolean = this.toolbarWidth <= 100;
         return (
-            <div className="presBox-buttons" style={{ background: Doc.ActivePresentation === this.rootDoc ? 'green' : undefined, display: !this.rootDoc._chromeHidden ? 'none' : undefined }}>
-                {isMini ? null : (
+            <div className="presBox-buttons" style={{ background: Doc.ActivePresentation === this.rootDoc ? Colors.LIGHT_BLUE : undefined, display: !this.rootDoc._chromeHidden ? 'none' : undefined }}>
+                {isMini || Doc.noviceMode ? null : (
                     <select className="presBox-viewPicker" style={{ display: this.layoutDoc.presStatus === 'edit' ? 'block' : 'none' }} onPointerDown={e => e.stopPropagation()} onChange={this.viewChanged} value={mode}>
                         <option onPointerDown={StopEvent} value={CollectionViewType.Stacking}>
                             List
@@ -2330,11 +2330,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                         <option onPointerDown={StopEvent} value={CollectionViewType.Tree}>
                             Tree
                         </option>
-                        {Doc.noviceMode ? null : (
-                            <option onPointerDown={StopEvent} value={CollectionViewType.Carousel3D}>
-                                3D Carousel
-                            </option>
-                        )}
+                        <option onPointerDown={StopEvent} value={CollectionViewType.Carousel3D}>
+                            3D Carousel
+                        </option>
                     </select>
                 )}
                 <div className="presBox-presentPanel" style={{ opacity: this.childDocs.length ? 1 : 0.3 }}>
@@ -2653,14 +2651,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                         ) : null}
                     </div>
 
-                    {
+                    {/* {
                         // if the document type is a presentation, then the collection stacking view has a "+ new slide" button at the bottom of the stack
                         <Tooltip title={<div className="dash-tooltip">{'Click on document to pin to presentaiton or make a marquee selection to pin your desired view'}</div>}>
                             <button className="add-slide-button" onPointerDown={this.startMarqueeCreateSlide}>
                                 + NEW SLIDE
                             </button>
                         </Tooltip>
-                    }
+                    } */}
                 </div>
             </div>
         );
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index bbdb4621e..2fe0c6e79 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -52,7 +52,7 @@ export class TopBar extends React.Component {
                     <span style={{color: Colors.LIGHT_GRAY, fontWeight: 200}}>brown</span><span style={{color: Colors.LIGHT_BLUE, fontWeight: 500}}>dash</span>
                 </div>
                 }
-                {Doc.ActiveDashboard && <Button
+                {Doc.ActiveDashboard && !Doc.noviceMode && <Button
                     text="Explore"
                     tooltip="Browsing mode for directly navigating to documents"
                     fontSize={FontSize.SECONDARY}
-- 
cgit v1.2.3-70-g09d2


From 87aaeef9b9be2a1faab1cc7a7cf35792d3c01252 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Wed, 21 Sep 2022 13:49:51 -0400
Subject: added resize back in

---
 src/client/views/DocumentDecorations.tsx | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 95025bf70..797730c10 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -29,6 +29,8 @@ import { DocumentView } from './nodes/DocumentView';
 import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
 import { ImageBox } from './nodes/ImageBox';
 import React = require('react');
+import { IconButton } from 'browndash-components';
+import { FaUndo } from 'react-icons/fa';
 
 @observer
 export class DocumentDecorations extends React.Component<{ PanelWidth: number; PanelHeight: number; boundsLeft: number; boundsTop: number }, { value: string }> {
@@ -719,12 +721,12 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                                 width: bounds.r - bounds.x + this._resizeBorderWidth + 'px',
                                 height: bounds.b - bounds.y + this._resizeBorderWidth + this._titleHeight + 'px',
                             }}>
-                            <div className="documentDecorations-topbar">
+                            {hideResizers ? null : (<div className="documentDecorations-topbar">
                                 {hideDeleteButton ? <div /> : topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')}
                                 {hideDeleteButton ? <div /> : topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')}
                                 {titleArea}
                                 {hideOpenButton ? null : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Tab (ctrl: as alias, shift: in new collection)')}
-                            </div>
+                            </div>)}
                             {hideResizers ? null : (
                                 <>
                                     <div key="tl" className={`documentDecorations-topLeftResizer ${resizerScheme}`} onPointerDown={this.onPointerDown} onContextMenu={e => e.preventDefault()} />
@@ -741,8 +743,8 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                                 </>
                             )}
 
-                            {!Doc.noviceMode && <div key="rot" className={`documentDecorations-rotation`} onPointerDown={this.onRotateDown} onContextMenu={e => e.preventDefault()}>
-                                {'⟲'}
+                            {useRotation && <div key="rot" className={`documentDecorations-rotation`} onPointerDown={this.onRotateDown} onContextMenu={e => e.preventDefault()}>
+                                <IconButton icon={<FaUndo/>} isCircle={true} hoverStyle={"lighten"} backgroundColor={Colors.DARK_GRAY} color={Colors.LIGHT_GRAY}/>
                             </div>}
 
                             {useRounding && (
-- 
cgit v1.2.3-70-g09d2


From 0bf2c263c82eb08a8f9545967c5907fc00be9a9f Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 22 Sep 2022 11:32:38 -0400
Subject: fixed presenting backward in presBox.  fixed context menu to appear
 above other widgets

---
 src/client/views/ContextMenu.scss               |  2 +-
 src/client/views/DocumentDecorations.tsx        | 25 +++++++++++++++----------
 src/client/views/global/globalCssVariables.scss |  2 +-
 src/client/views/nodes/trails/PresBox.tsx       | 25 +++++++++++++++----------
 4 files changed, 32 insertions(+), 22 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss
index 1e6a377de..cbe14060a 100644
--- a/src/client/views/ContextMenu.scss
+++ b/src/client/views/ContextMenu.scss
@@ -3,7 +3,7 @@
 .contextMenu-cont {
     position: absolute;
     display: flex;
-    z-index: 100000;
+    z-index: $contextMenu-zindex;
     box-shadow: 0px 3px 4px rgba(0, 0, 0, 30%);
     flex-direction: column;
     background: whitesmoke;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 797730c10..4675571c2 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -31,6 +31,7 @@ import { ImageBox } from './nodes/ImageBox';
 import React = require('react');
 import { IconButton } from 'browndash-components';
 import { FaUndo } from 'react-icons/fa';
+import { VideoBox } from './nodes/VideoBox';
 
 @observer
 export class DocumentDecorations extends React.Component<{ PanelWidth: number; PanelHeight: number; boundsLeft: number; boundsTop: number }, { value: string }> {
@@ -678,7 +679,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
         bounds.b = Math.max(bounds.y, Math.max(topBounds, Math.min(window.innerHeight, bounds.b + this._resizeBorderWidth / 2 + this._linkBoxHeight) - this._resizeBorderWidth / 2 - this._linkBoxHeight));
 
         // Rotation constants: Only allow rotation on ink and images
-        const useRotation = seldoc.ComponentView instanceof InkingStroke || seldoc.ComponentView instanceof ImageBox;
+        const useRotation = seldoc.ComponentView instanceof InkingStroke || seldoc.ComponentView instanceof ImageBox || seldoc.ComponentView instanceof VideoBox;
         const rotation = NumCast(seldoc.rootDoc._jitterRotation);
 
         const resizerScheme = colorScheme ? 'documentDecorations-resizer' + colorScheme : '';
@@ -721,12 +722,14 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                                 width: bounds.r - bounds.x + this._resizeBorderWidth + 'px',
                                 height: bounds.b - bounds.y + this._resizeBorderWidth + this._titleHeight + 'px',
                             }}>
-                            {hideResizers ? null : (<div className="documentDecorations-topbar">
-                                {hideDeleteButton ? <div /> : topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')}
-                                {hideDeleteButton ? <div /> : topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')}
-                                {titleArea}
-                                {hideOpenButton ? null : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Tab (ctrl: as alias, shift: in new collection)')}
-                            </div>)}
+                            {hideResizers ? null : (
+                                <div className="documentDecorations-topbar">
+                                    {hideDeleteButton ? <div /> : topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')}
+                                    {hideDeleteButton ? <div /> : topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')}
+                                    {titleArea}
+                                    {hideOpenButton ? null : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Tab (ctrl: as alias, shift: in new collection)')}
+                                </div>
+                            )}
                             {hideResizers ? null : (
                                 <>
                                     <div key="tl" className={`documentDecorations-topLeftResizer ${resizerScheme}`} onPointerDown={this.onPointerDown} onContextMenu={e => e.preventDefault()} />
@@ -743,9 +746,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                                 </>
                             )}
 
-                            {useRotation && <div key="rot" className={`documentDecorations-rotation`} onPointerDown={this.onRotateDown} onContextMenu={e => e.preventDefault()}>
-                                <IconButton icon={<FaUndo/>} isCircle={true} hoverStyle={"lighten"} backgroundColor={Colors.DARK_GRAY} color={Colors.LIGHT_GRAY}/>
-                            </div>}
+                            {useRotation && (
+                                <div key="rot" className={`documentDecorations-rotation`} onPointerDown={this.onRotateDown} onContextMenu={e => e.preventDefault()}>
+                                    <IconButton icon={<FaUndo />} isCircle={true} hoverStyle={'lighten'} backgroundColor={Colors.DARK_GRAY} color={Colors.LIGHT_GRAY} />
+                                </div>
+                            )}
 
                             {useRounding && (
                                 <div
diff --git a/src/client/views/global/globalCssVariables.scss b/src/client/views/global/globalCssVariables.scss
index ac2c04aaa..e68f9abe3 100644
--- a/src/client/views/global/globalCssVariables.scss
+++ b/src/client/views/global/globalCssVariables.scss
@@ -47,7 +47,7 @@ $topbar-height: 37px;
 $antimodemenu-height: 36px;
 
 // dragged items
-$contextMenu-zindex: 100000; // context menu shows up over everything
+$contextMenu-zindex: 100002; // context menu shows up over everything
 $radialMenu-zindex: 100000; // context menu shows up over everything
 
 // borders
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 042c55a46..69f817d79 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -234,8 +234,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     //TODO: al: it seems currently that tempMedia doesn't stop onslidechange after clicking the button; the time the tempmedia stop depends on the start & end time
     // TODO: to handle child slides (entering into subtrail and exiting), also the next() and back() functions
     // No more frames in current doc and next slide is defined, therefore move to next slide
-    nextSlide = (activeNext: Doc) => {
-        let nextSelected = this.itemIndex + 1;
+    nextSlide = (slideNum?: number) => {
+        let nextSelected = slideNum ?? this.itemIndex + 1;
         this.gotoDocument(nextSelected, this.activeItem);
         for (nextSelected = nextSelected + 1; nextSelected < this.childDocs.length; nextSelected++) {
             if (this.childDocs[nextSelected].groupWithUp) {
@@ -261,10 +261,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             this.nextInternalFrame(targetDoc, activeItem);
         } else if (this.childDocs[this.itemIndex + 1] !== undefined) {
             // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide
-            this.nextSlide(activeNext);
+            const slides = DocListCast(this.rootDoc[StrCast(this.presFieldKey, 'data')]);
+            const curLast = this.selectedArray.size ? Math.max(...Array.from(this.selectedArray).map(d => slides.indexOf(DocCast(d)))) : this.itemIndex;
+            this.nextSlide(curLast + 1);
         } else if (this.childDocs[this.itemIndex + 1] === undefined && (this.layoutDoc.presLoop || this.layoutDoc.presStatus === PresStatus.Edit)) {
             // Case 3: Last slide and presLoop is toggled ON or it is in Edit mode
-            this.gotoDocument(0, this.activeItem);
+            this.nextSlide(0);
         }
     };
 
@@ -280,8 +282,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         let prevSelected = this.itemIndex;
         // Functionality for group with up
         let didZoom = activeItem.presMovement;
-        for (; !didZoom && prevSelected > 0 && this.childDocs[prevSelected].groupButton; prevSelected--) {
-            didZoom = this.childDocs[prevSelected].presMovement;
+        for (; prevSelected > 0 && this.childDocs[Math.max(0, prevSelected - 1)].groupWithUp; prevSelected--) {
+            didZoom = didZoom === 'none' ? this.childDocs[prevSelected].presMovement : didZoom;
         }
         if (lastFrame !== undefined && curFrame >= 1) {
             // Case 1: There are still other frames and should go through all frames before going to previous slide
@@ -289,7 +291,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
         } else if (activeItem && this.childDocs[this.itemIndex - 1] !== undefined) {
             // Case 2: There are no other frames so it should go to the previous slide
             prevSelected = Math.max(0, prevSelected - 1);
-            this.gotoDocument(prevSelected, activeItem);
+            this.nextSlide(prevSelected);
+            this.rootDoc._itemIndex = prevSelected;
             if (NumCast(prevTargetDoc.lastFrame) > 0) prevTargetDoc._currentFrame = NumCast(prevTargetDoc.lastFrame);
         } else if (this.childDocs[this.itemIndex - 1] === undefined && this.layoutDoc.presLoop) {
             // Case 3: Pres loop is on so it should go to the last slide
@@ -2458,12 +2461,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 <div
                     className="presPanel-button"
                     style={{ opacity: presStart ? 0.4 : 1 }}
-                    onClick={() => {
+                    onClick={e => {
                         this.back();
                         if (this._presTimer) {
                             clearTimeout(this._presTimer);
                             this.layoutDoc.presStatus = PresStatus.Manual;
                         }
+                        e.stopPropagation();
                     }}>
                     <FontAwesomeIcon icon={'arrow-left'} />
                 </div>
@@ -2475,18 +2479,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 <div
                     className="presPanel-button"
                     style={{ opacity: presEnd ? 0.4 : 1 }}
-                    onClick={() => {
+                    onClick={e => {
                         this.next();
                         if (this._presTimer) {
                             clearTimeout(this._presTimer);
                             this.layoutDoc.presStatus = PresStatus.Manual;
                         }
+                        e.stopPropagation();
                     }}>
                     <FontAwesomeIcon icon={'arrow-right'} />
                 </div>
                 <div className="presPanel-divider"></div>
                 <Tooltip title={<div className="dash-tooltip">{'Click to return to 1st slide'}</div>}>
-                    <div className="presPanel-button" style={{ border: 'solid 1px white' }} onClick={() => this.gotoDocument(0, this.activeItem)}>
+                    <div className="presPanel-button" style={{ border: 'solid 1px white' }} onClick={() => this.nextSlide(0)}>
                         <b>1</b>
                     </div>
                 </Tooltip>
-- 
cgit v1.2.3-70-g09d2


From 8e8cca45755426e2921e2de78556ad60d79a98a8 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 4 Oct 2022 11:54:55 -0400
Subject: fix to show close and open icons of hideResizers documents. fixes for
 native size control of text and freeform collections.  fixes for lightbox
 view of native size collections.   fix for 'false' script.

---
 src/client/documents/Documents.ts                  |  1 +
 src/client/views/DocumentDecorations.tsx           | 24 ++++++++++------------
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  5 ++++-
 src/fields/Doc.ts                                  |  6 ++++++
 src/fields/ScriptField.ts                          |  2 +-
 5 files changed, 23 insertions(+), 15 deletions(-)

(limited to 'src/client/views/DocumentDecorations.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index fb68fba38..cd647f5e8 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -396,6 +396,7 @@ export namespace Docs {
                         _yMargin: 10,
                         nativeDimModifiable: true,
                         treeViewGrowsHorizontally: true,
+                        nativeHeightUnfrozen: true,
                         forceReflow: true,
                         links: '@links(self)',
                     },
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 4675571c2..d5db45494 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -1,8 +1,10 @@
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@material-ui/core';
+import { IconButton } from 'browndash-components';
 import { action, computed, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
+import { FaUndo } from 'react-icons/fa';
 import { DateField } from '../../fields/DateField';
 import { AclAdmin, AclEdit, DataSym, Doc, DocListCast, Field, HeightSym, WidthSym } from '../../fields/Doc';
 import { Document } from '../../fields/documentSchemas';
@@ -28,10 +30,8 @@ import { LightboxView } from './LightboxView';
 import { DocumentView } from './nodes/DocumentView';
 import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
 import { ImageBox } from './nodes/ImageBox';
-import React = require('react');
-import { IconButton } from 'browndash-components';
-import { FaUndo } from 'react-icons/fa';
 import { VideoBox } from './nodes/VideoBox';
+import React = require('react');
 
 @observer
 export class DocumentDecorations extends React.Component<{ PanelWidth: number; PanelHeight: number; boundsLeft: number; boundsTop: number }, { value: string }> {
@@ -503,7 +503,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                     }
                     let actualdW = Math.max(width + dW * scale, 20);
                     let actualdH = Math.max(height + dH * scale, 20);
-                    const fixedAspect = nwidth && nheight && (!doc._fitWidth || e.ctrlKey || doc.nativeHeightUnfrozen);
+                    const fixedAspect = nwidth && nheight && (!doc._fitWidth || e.ctrlKey || doc.nativeHeightUnfrozen || doc.nativeDimModifiable);
                     if (fixedAspect) {
                         if ((Math.abs(dW) > Math.abs(dH) && ((!dragBottom && !dragTop) || !modifyNativeDim)) || dragRight) {
                             if (dragRight && modifyNativeDim) {
@@ -534,7 +534,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                             } else doc._height = actualdH;
                         }
                     } else {
-                        const maxHeight = 0; //Math.max(nheight, NumCast(doc.scrollHeight, NumCast(doc[docView.LayoutFieldKey + '-scrollHeight']))) * docView.NativeDimScaling();
+                        const maxHeight = doc.nativHeightUnfrozen || !nheight ? 0 : Math.max(nheight, NumCast(doc.scrollHeight, NumCast(doc[docView.LayoutFieldKey + '-scrollHeight']))) * docView.NativeDimScaling();
                         dH && (doc._height = actualdH > maxHeight && maxHeight ? maxHeight : actualdH);
                         dW && (doc._width = actualdW);
                         dH && (doc._autoHeight = false);
@@ -722,14 +722,12 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
                                 width: bounds.r - bounds.x + this._resizeBorderWidth + 'px',
                                 height: bounds.b - bounds.y + this._resizeBorderWidth + this._titleHeight + 'px',
                             }}>
-                            {hideResizers ? null : (
-                                <div className="documentDecorations-topbar">
-                                    {hideDeleteButton ? <div /> : topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')}
-                                    {hideDeleteButton ? <div /> : topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')}
-                                    {titleArea}
-                                    {hideOpenButton ? null : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Tab (ctrl: as alias, shift: in new collection)')}
-                                </div>
-                            )}
+                            <div className="documentDecorations-topbar">
+                                {hideDeleteButton ? <div /> : topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')}
+                                {hideResizers || hideDeleteButton ? <div /> : topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')}
+                                {hideResizers ? <div /> : titleArea}
+                                {hideOpenButton ? <div /> : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Lightbox (ctrl: as alias, shift: in new collection)')}
+                            </div>
                             {hideResizers ? null : (
                                 <>
                                     <div key="tl" className={`documentDecorations-topLeftResizer ${resizerScheme}`} onPointerDown={this.onPointerDown} onContextMenu={e => e.preventDefault()} />
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 7b6944e1e..93bf143df 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -156,7 +156,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     }
     @computed get cachedCenteringShiftY(): number {
         const scaling = this.fitContentsToBox || !this.nativeDimScaling ? 1 : this.nativeDimScaling;
-        return this.props.isAnnotationOverlay ? 0 : this.props.PanelHeight() / 2 / scaling; // shift so pan position is at center of window for non-overlay collections
+        // if freeform has a native aspect, then the panel height needs to be adjusted to match it
+        const aspect = this.props.DocumentView?.().nativeHeight ? this.props.DocumentView?.().nativeHeight / this.props.DocumentView?.().nativeWidth : 1;
+        return this.props.isAnnotationOverlay ? 0 : (aspect * this.props.PanelHeight()) / 2 / scaling; // shift so pan position is at center of window for non-overlay collections
     }
     @computed get cachedGetLocalTransform(): Transform {
         return Transform.Identity()
@@ -190,6 +192,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick);
     elementFunc = () => this._layoutElements;
     shrinkWrap = () => {
+        if (this.props.DocumentView?.().nativeWidth) return;
         const vals = this.fitToContentVals;
         this.layoutDoc._panX = vals.bounds.cx;
         this.layoutDoc._panY = vals.bounds.cy;
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index ea3c122a4..0ceaff968 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1402,11 +1402,17 @@ export namespace Doc {
                 layoutDoc._viewScale = NumCast(layoutDoc._viewScale, 1) * contentScale;
                 layoutDoc._nativeWidth = undefined;
                 layoutDoc._nativeHeight = undefined;
+                layoutDoc._forceReflow = undefined;
+                layoutDoc._nativeHeightUnfrozen = undefined;
+                layoutDoc._nativeDimModifiable = undefined;
             } else {
                 layoutDoc._autoHeight = false;
                 if (!Doc.NativeWidth(layoutDoc)) {
                     layoutDoc._nativeWidth = NumCast(layoutDoc._width, panelWidth);
                     layoutDoc._nativeHeight = NumCast(layoutDoc._height, panelHeight);
+                    layoutDoc._forceReflow = true;
+                    layoutDoc._nativeHeightUnfrozen = true;
+                    layoutDoc._nativeDimModifiable = true;
                 }
             }
         });
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index 3cb50a4c0..4896c027d 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -104,7 +104,7 @@ export class ScriptField extends ObjectField {
         }
         this.rawscript = rawscript;
         this.setterscript = setterscript;
-        this.script = script ?? (CompileScript('false') as CompiledScript);
+        this.script = script ?? (CompileScript('false', { addReturn: true }) as CompiledScript);
     }
 
     //     init(callback: (res: Field) => any) {
-- 
cgit v1.2.3-70-g09d2

