From bbf482ed6446899bd29e005184ecc779470658c7 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 25 Nov 2019 15:12:55 -0500
Subject: title template fixes for tree/stacking views.

---
 src/client/views/collections/CollectionTreeView.tsx | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

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

diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 8b993820b..261354ba8 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -43,6 +43,7 @@ export interface TreeViewProps {
     pinToPres: (document: Doc) => void;
     panelWidth: () => number;
     panelHeight: () => number;
+    ChromeHeight: undefined | (() => number);
     addDocument: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean;
     indentDocument?: () => void;
     ScreenToLocalTransform: () => Transform;
@@ -233,8 +234,8 @@ class TreeView extends React.Component<TreeViewProps> {
     docTransform = () => {
         let { scale, translateX, translateY } = Utils.GetScreenTransform(this._dref.current!);
         let outerXf = this.props.outerXf();
-        let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
-        let finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1]);
+        let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY );
+        let finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1]+ (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0));
         return finalXf;
     }
     docWidth = () => {
@@ -272,7 +273,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] :
                     DocListCast(contents), this.props.treeViewId, doc, undefined, key, addDoc, remDoc, this.move,
                     this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active,
-                    this.props.panelWidth, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen,
+                    this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen,
                     [...this.props.renderedIds, doc[Id]]);
             } else {
                 contentElement = <EditableView
@@ -305,7 +306,7 @@ class TreeView extends React.Component<TreeViewProps> {
                     TreeView.GetChildElements(docs, this.props.treeViewId, Doc.Layout(this.props.document),
                         this.templateDataDoc, expandKey, addDoc, remDoc, this.move,
                         this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
-                        this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen,
+                        this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen,
                         [...this.props.renderedIds, this.props.document[Id]])}
             </ul >;
         } else if (this.treeViewExpandedView === "fields") {
@@ -414,6 +415,7 @@ class TreeView extends React.Component<TreeViewProps> {
         outerXf: () => { translateX: number, translateY: number },
         active: (outsideReaction?: boolean) => boolean,
         panelWidth: () => number,
+        ChromeHeight: undefined| (() => number),
         renderDepth: number,
         showHeaderFields: () => boolean,
         preventTreeViewOpen: boolean,
@@ -487,6 +489,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 addDocument={addDocument}
                 panelWidth={rowWidth}
                 panelHeight={rowHeight}
+                ChromeHeight={ChromeHeight}
                 moveDocument={move}
                 dropAction={dropAction}
                 addDocTab={addDocTab}
@@ -591,7 +594,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
                     {
                         TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.Document, this.props.DataDoc, this.props.fieldKey, addDoc, this.remove,
                             moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
-                            this.outerXf, this.props.active, this.props.PanelWidth, this.props.renderDepth, () => !this.props.Document.hideHeaderFields,
+                            this.outerXf, this.props.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => !this.props.Document.hideHeaderFields,
                             BoolCast(this.props.Document.preventTreeViewOpen), [])
                     }
                 </ul>
-- 
cgit v1.2.3-70-g09d2


From 4cf3b0a4673a00f0e1de107b29a0c0b658266f46 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 26 Nov 2019 13:26:34 -0500
Subject: fixed tree view sorting (a little) and kept title box editable after
 tabbing.

---
 .../views/collections/CollectionTreeView.scss      |  3 +
 .../views/collections/CollectionTreeView.tsx       | 72 +++++++++++++++-------
 .../views/collections/CollectionViewChromes.tsx    | 15 +++--
 .../CollectionFreeFormLinkView.tsx                 | 15 +++--
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  2 +-
 src/client/views/nodes/DocumentView.tsx            |  9 +--
 6 files changed, 74 insertions(+), 42 deletions(-)

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

diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index 7d0c900a6..8b12395a7 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -114,6 +114,9 @@
 .treeViewItem-header {
     border: transparent 1px solid;
     display: flex;
+    .editableView-container-editing-oneLine {
+        min-width: 15px;
+    }
 }
 
 .treeViewItem-header-above {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 261354ba8..a21bc6c14 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,7 +1,7 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faAngleRight, faArrowsAltH, faBell, faCamera, faCaretDown, faCaretRight, faCaretSquareDown, faCaretSquareRight, faExpand, faMinus, faPlus, faTrash, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable } from "mobx";
+import { action, computed, observable, trace, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from '../../../new_fields/Doc';
 import { Id } from '../../../new_fields/FieldSymbols';
@@ -82,10 +82,11 @@ class TreeView extends React.Component<TreeViewProps> {
     private _header?: React.RefObject<HTMLDivElement> = React.createRef();
     private _treedropDisposer?: DragManager.DragDropDisposer;
     private _dref = React.createRef<HTMLDivElement>();
+    get displayName() { return "TreeView(" + this.props.document.title + ")"; }  // this makes mobx trace() statements more descriptive
     get defaultExpandedView() { return this.childDocs ? this.fieldKey : StrCast(this.props.document.defaultExpandedView, "fields"); }
     @observable _overrideTreeViewOpen = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state
     set treeViewOpen(c: boolean) { if (this.props.preventTreeViewOpen) this._overrideTreeViewOpen = c; else this.props.document.treeViewOpen = c; }
-    @computed get treeViewOpen() { return (BoolCast(this.props.document.treeViewOpen) && !this.props.preventTreeViewOpen) || this._overrideTreeViewOpen; }
+    @computed get treeViewOpen() { trace(); return (this.props.document.treeViewOpen && !this.props.preventTreeViewOpen) || this._overrideTreeViewOpen; }
     @computed get treeViewExpandedView() { return StrCast(this.props.document.treeViewExpandedView, this.defaultExpandedView); }
     @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.document.maxEmbedHeight, 300); }
     @computed get dataDoc() { return this.templateDataDoc ? this.templateDataDoc : this.props.document; }
@@ -110,7 +111,7 @@ class TreeView extends React.Component<TreeViewProps> {
         return this.props.dataDoc;
     }
     @computed get boundsOfCollectionDocument() {
-        return StrCast(this.props.document.type).indexOf(DocumentType.COL) === -1 ? undefined :
+        return StrCast(this.props.document.type).indexOf(DocumentType.COL) === -1 || !DocListCast(this.props.document[this.fieldKey]).length ? undefined :
             Doc.ComputeContentBounds(DocListCast(this.props.document[this.fieldKey]));
     }
 
@@ -158,22 +159,30 @@ class TreeView extends React.Component<TreeViewProps> {
 
     editableView = (key: string, style?: string) => (<EditableView
         oneLine={true}
-        display={"inline"}
+        display={"inline-block"}
         editing={this.dataDoc[Id] === TreeView.loadId}
         contents={StrCast(this.props.document[key])}
-        height={36}
+        height={12}
         fontStyle={style}
         fontSize={12}
         GetValue={() => StrCast(this.props.document[key])}
         SetValue={undoBatch((value: string) => Doc.SetInPlace(this.props.document, key, value, false) || true)}
         OnFillDown={undoBatch((value: string) => {
             Doc.SetInPlace(this.props.document, key, value, false);
-            let doc = this.props.document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.document.layoutCustom)) : undefined;
-            if (!doc) doc = Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
+            let layoutDoc = this.props.document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.document.layoutCustom)) : undefined;
+            let doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
             TreeView.loadId = doc[Id];
             return this.props.addDocument(doc);
         })}
-        OnTab={() => { TreeView.loadId = ""; this.props.indentDocument && this.props.indentDocument(); }}
+        OnTab={undoBatch(() => {
+            TreeView.loadId = this.dataDoc[Id];
+            this.props.indentDocument?.();
+            setTimeout(() => {  // unsetting/setting brushing for this doc will recreate & refocus this editableView after all other treeview changes have been made to the Dom (which may remove focus from this document).
+                Doc.UnBrushDoc(this.props.document);
+                Doc.BrushDoc(this.props.document);
+                TreeView.loadId = "";
+            }, 0);
+        })}
     />)
 
     onWorkspaceContextMenu = (e: React.MouseEvent): void => {
@@ -207,7 +216,7 @@ class TreeView extends React.Component<TreeViewProps> {
         let rect = this._header!.current!.getBoundingClientRect();
         let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2);
         let before = x[1] < bounds[1];
-        let inside = x[0] > bounds[0] + 75 || (!before && this.treeViewOpen);
+        let inside = x[0] > bounds[0] + 75 || (!before && this.treeViewOpen && DocListCast(this.dataDoc[this.fieldKey]).length);
         if (de.data instanceof DragManager.LinkDragData) {
             let sourceDoc = de.data.linkSourceDocument;
             let destDoc = this.props.document;
@@ -234,8 +243,8 @@ class TreeView extends React.Component<TreeViewProps> {
     docTransform = () => {
         let { scale, translateX, translateY } = Utils.GetScreenTransform(this._dref.current!);
         let outerXf = this.props.outerXf();
-        let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY );
-        let finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1]+ (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0));
+        let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
+        let finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1] + (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0));
         return finalXf;
     }
     docWidth = () => {
@@ -258,8 +267,10 @@ class TreeView extends React.Component<TreeViewProps> {
         })());
     }
 
-    expandedField = (doc: Doc) => {
+    @computed get expandedField() {
+        trace();
         let ids: { [key: string]: string } = {};
+        let doc = this.props.document;
         doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
 
         let rows: JSX.Element[] = [];
@@ -296,6 +307,7 @@ class TreeView extends React.Component<TreeViewProps> {
     noOverlays = (doc: Doc) => ({ title: "", caption: "" });
 
     @computed get renderContent() {
+        trace();
         const expandKey = this.treeViewExpandedView === this.fieldKey ? this.fieldKey : this.treeViewExpandedView === "links" ? "links" : undefined;
         if (expandKey !== undefined) {
             let remDoc = (doc: Doc) => this.remove(doc, expandKey);
@@ -311,7 +323,7 @@ class TreeView extends React.Component<TreeViewProps> {
             </ul >;
         } else if (this.treeViewExpandedView === "fields") {
             return <ul><div ref={this._dref} style={{ display: "inline-block" }} key={this.props.document[Id] + this.props.document.title}>
-                {this.expandedField(this.props.document)}
+                {this.expandedField}
             </div></ul>;
         } else {
             let layoutDoc = Doc.Layout(this.props.document);
@@ -342,6 +354,7 @@ class TreeView extends React.Component<TreeViewProps> {
 
     @computed
     get renderBullet() {
+        trace();
         return <div className="bullet" title="view inline" onClick={action((e: React.MouseEvent) => { this.treeViewOpen = !this.treeViewOpen; e.stopPropagation(); })} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}>
             {<FontAwesomeIcon icon={!this.treeViewOpen ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down")} />}
         </div>;
@@ -387,6 +400,7 @@ class TreeView extends React.Component<TreeViewProps> {
     }
 
     render() {
+        trace();
         return <div className="treeViewItem-container" ref={this.createTreeDropTarget} onContextMenu={this.onWorkspaceContextMenu}>
             <li className="collection-child">
                 <div className="treeViewItem-header" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
@@ -400,7 +414,7 @@ class TreeView extends React.Component<TreeViewProps> {
         </div>;
     }
     public static GetChildElements(
-        docs: Doc[],
+        childDocs: Doc[],
         treeViewId: string,
         containingCollection: Doc,
         dataDoc: Doc | undefined,
@@ -415,7 +429,7 @@ class TreeView extends React.Component<TreeViewProps> {
         outerXf: () => { translateX: number, translateY: number },
         active: (outsideReaction?: boolean) => boolean,
         panelWidth: () => number,
-        ChromeHeight: undefined| (() => number),
+        ChromeHeight: undefined | (() => number),
         renderDepth: number,
         showHeaderFields: () => boolean,
         preventTreeViewOpen: boolean,
@@ -423,12 +437,27 @@ class TreeView extends React.Component<TreeViewProps> {
     ) {
         const viewSpecScript = Cast(containingCollection.viewSpecScript, ScriptField);
         if (viewSpecScript) {
-            docs = docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result);
+            childDocs = childDocs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result);
         }
 
-        let ascending = Cast(containingCollection.sortAscending, "boolean", null);
+        let docs = childDocs.slice();
+        let dataExtension = containingCollection[key + "_ext"] as Doc;
+        let ascending = dataExtension && BoolCast(dataExtension.sortAscending, null);
         if (ascending !== undefined) {
-            docs.sort(function (a, b): 1 | -1 {
+
+            let sortAlphaNum = (a: string, b: string): 0 | 1 | -1 => {
+                var reN = /[0-9]*$/;
+                var aA = a.replace(reN, ""); // get rid of trailing numbers
+                var bA = b.replace(reN, "");
+                if (aA === bA) {  // if header string matches, then compare numbers numerically
+                    var aN = parseInt(a.match(reN)![0], 10);
+                    var bN = parseInt(b.match(reN)![0], 10);
+                    return aN === bN ? 0 : aN > bN ? 1 : -1;
+                } else {
+                    return aA > bA ? 1 : -1;
+                }
+            }
+            docs.sort(function (a, b): 0 | 1 | -1 {
                 let descA = ascending ? b : a;
                 let descB = ascending ? a : b;
                 let first = descA.title;
@@ -438,7 +467,7 @@ class TreeView extends React.Component<TreeViewProps> {
                     return (first - second) > 0 ? 1 : -1;
                 }
                 if (typeof first === 'string' && typeof second === 'string') {
-                    return first > second ? 1 : -1;
+                    return sortAlphaNum(first, second);
                 }
                 if (typeof first === 'boolean' && typeof second === 'boolean') {
                     // if (first === second) { // bugfixing?: otherwise, the list "flickers" because the list is resorted during every load
@@ -565,6 +594,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
     }
 
     render() {
+        trace();
         let dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
         let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before, false, false, false);
         let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
@@ -584,8 +614,8 @@ export class CollectionTreeView extends CollectionSubView(Document) {
                     SetValue={undoBatch((value: string) => Doc.SetInPlace(this.dataDoc, "title", value, false) || true)}
                     OnFillDown={undoBatch((value: string) => {
                         Doc.SetInPlace(this.dataDoc, "title", value, false);
-                        let doc = this.props.Document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.Document.layoutCustom)) : undefined;
-                        if (!doc) doc = Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
+                        let layoutDoc = this.props.Document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.Document.layoutCustom)) : undefined;
+                        let doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
                         TreeView.loadId = doc[Id];
                         Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, this.childDocs.length ? this.childDocs[0] : undefined, true, false, false, false);
                     })} />
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index cfc6c2a3f..06fca7c38 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -624,12 +624,19 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionViewCh
 @observer
 export class CollectionTreeViewChrome extends React.Component<CollectionViewChromeProps> {
 
-    @computed private get descending() { return Cast(this.props.CollectionView.props.Document.sortAscending, "boolean", null); }
+    get dataExtension() {
+        return this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey + "_ext"] as Doc;
+    }
+    @computed private get descending() {
+        return this.dataExtension && Cast(this.dataExtension.sortAscending, "boolean", null);
+    }
 
     @action toggleSort = () => {
-        if (this.props.CollectionView.props.Document.sortAscending) this.props.CollectionView.props.Document.sortAscending = undefined;
-        else if (this.props.CollectionView.props.Document.sortAscending === undefined) this.props.CollectionView.props.Document.sortAscending = false;
-        else this.props.CollectionView.props.Document.sortAscending = true;
+        if (this.dataExtension) {
+            if (this.dataExtension.sortAscending) this.dataExtension.sortAscending = undefined;
+            else if (this.dataExtension.sortAscending === undefined) this.dataExtension.sortAscending = false;
+            else this.dataExtension.sortAscending = true;
+        }
     }
 
     render() {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index 73b45edc6..b00728079 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -6,8 +6,9 @@ import "./CollectionFreeFormLinkView.scss";
 import React = require("react");
 import v5 = require("uuid/v5");
 import { DocumentType } from "../../../documents/DocumentTypes";
-import { observable, action, reaction, IReactionDisposer } from "mobx";
+import { observable, action, reaction, IReactionDisposer, trace } from "mobx";
 import { StrCast, Cast } from "../../../../new_fields/Types";
+import { TraceMobx } from "../../../../new_fields/util";
 
 export interface CollectionFreeFormLinkViewProps {
     A: DocumentView;
@@ -17,14 +18,14 @@ export interface CollectionFreeFormLinkViewProps {
 
 @observer
 export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFormLinkViewProps> {
-    @observable _opacity: number = 1;
-    @observable _update: number = 0;
+    @observable _opacity: number = 0;
     _anchorDisposer: IReactionDisposer | undefined;
     @action
     componentDidMount() {
-        setTimeout(action(() => this._opacity = 0.05), 750);
         this._anchorDisposer = reaction(() => [this.props.A.props.ScreenToLocalTransform(), this.props.B.props.ScreenToLocalTransform()],
-            () => {
+            action(() => {
+                setTimeout(action(() => this._opacity = 1), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render()
+                setTimeout(action(() => this._opacity = 0.05), 750); // this will unhighlight the link line.
                 let acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
                 let bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
                 let adiv = (acont.length ? acont[0] : this.props.A.ContentDiv!);
@@ -45,8 +46,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
                 this.props.A.props.Document[afield + "_y"] = (apt.point.y - abounds.top) / abounds.height * 100;
                 this.props.A.props.Document[bfield + "_x"] = (bpt.point.x - bbounds.left) / bbounds.width * 100;
                 this.props.A.props.Document[bfield + "_y"] = (bpt.point.y - bbounds.top) / bbounds.height * 100;
-                this._update++;
-            }
+            })
             , { fireImmediately: true });
     }
     @action
@@ -55,7 +55,6 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
     }
 
     render() {
-        let y = this._update;
         let acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
         let bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
         let a = (acont.length ? acont[0] : this.props.A.ContentDiv!).getBoundingClientRect();
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index c85b59488..2b079fe50 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -94,7 +94,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                     this.layoutDoc.opacity === 0 ? undefined :  // if it's not visible, then no shadow
                         this.layoutDoc.z ? `#9c9396  ${StrCast(this.layoutDoc.boxShadow, "10px 10px 0.9vw")}` :  // if it's a floating doc, give it a big shadow
                             this.clusterColor ? (`${this.clusterColor} ${StrCast(this.layoutDoc.boxShadow, `0vw 0vw ${(this.layoutDoc.isBackground ? 100 : 50) / this.props.ContentScaling()}px`)}`) :  // if it's just in a cluster, make the shadown roughly match the cluster border extent
-                                this.layoutDoc.isBackground ? `1px 1px 1px ${this.clusterColor}` :  // if it's a background & has a cluster color, make the shadow spread really big
+                                this.layoutDoc.isBackground ? undefined :  // if it's a background & has a cluster color, make the shadow spread really big
                                     StrCast(this.layoutDoc.boxShadow, ""),
                 borderRadius: this.borderRounding(),
                 transform: this.transform,
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 8486c0f34..057b4eecd 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -687,14 +687,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         let highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc.viewType !== CollectionViewType.Linear;
         return <div className={`documentView-node${this.topMost ? "-topmost" : ""}`} ref={this._mainCont}
             onDrop={this.onDrop} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
-            onPointerEnter={e => {
-                console.log("Brush" + this.props.Document.title);
-                Doc.BrushDoc(this.props.Document);
-            }} onPointerLeave={e => {
-                console.log("UnBrush" + this.props.Document.title);
-                Doc.UnBrushDoc(this.props.Document);
-
-            }}
+            onPointerEnter={e => Doc.BrushDoc(this.props.Document)} onPointerLeave={e => Doc.UnBrushDoc(this.props.Document)}
             style={{
                 transition: this.Document.isAnimating ? ".5s linear" : StrCast(this.Document.transition),
                 pointerEvents: this.ignorePointerEvents ? "none" : "all",
-- 
cgit v1.2.3-70-g09d2


From 6cd6e035fc67812afd7a40f8abd0f07f8874f04a Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 26 Nov 2019 14:34:41 -0500
Subject: fixes for tree view drag drop with images.

---
 src/client/views/EditableView.tsx                  |  4 +-
 .../views/collections/CollectionTreeView.tsx       | 62 +++++++++++++---------
 src/client/views/nodes/ImageBox.scss               | 25 ++++-----
 src/client/views/nodes/ImageBox.tsx                | 59 ++++++++++----------
 4 files changed, 79 insertions(+), 71 deletions(-)

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

diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 8e86f58ee..f78b61892 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -21,7 +21,7 @@ export interface EditableProps {
 
     OnFillDown?(value: string): void;
 
-    OnTab?(): void;
+    OnTab?(shift?: boolean): void;
 
     /**
      * The contents to render when not editing
@@ -79,7 +79,7 @@ export class EditableView extends React.Component<EditableProps> {
         if (e.key === "Tab") {
             e.stopPropagation();
             this.finalizeEdit(e.currentTarget.value, e.shiftKey);
-            this.props.OnTab && this.props.OnTab();
+            this.props.OnTab && this.props.OnTab(e.shiftKey);
         } else if (e.key === "Enter") {
             e.stopPropagation();
             if (!e.ctrlKey) {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index a21bc6c14..42cdd1455 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,7 +1,7 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faAngleRight, faArrowsAltH, faBell, faCamera, faCaretDown, faCaretRight, faCaretSquareDown, faCaretSquareRight, faExpand, faMinus, faPlus, faTrash, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable, trace, runInAction } from "mobx";
+import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from '../../../new_fields/Doc';
 import { Id } from '../../../new_fields/FieldSymbols';
@@ -34,6 +34,7 @@ export interface TreeViewProps {
     document: Doc;
     dataDoc?: Doc;
     containingCollection: Doc;
+    prevSibling?: Doc;
     renderDepth: number;
     deleteDoc: (doc: Doc) => boolean;
     ruleProvider: Doc | undefined;
@@ -46,12 +47,13 @@ export interface TreeViewProps {
     ChromeHeight: undefined | (() => number);
     addDocument: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean;
     indentDocument?: () => void;
+    outdentDocument?: () => void;
     ScreenToLocalTransform: () => Transform;
     outerXf: () => { translateX: number, translateY: number };
     treeViewId: string;
     parentKey: string;
     active: (outsideReaction?: boolean) => boolean;
-    showHeaderFields: () => boolean;
+    hideHeaderFields: () => boolean;
     preventTreeViewOpen: boolean;
     renderedIds: string[];
 }
@@ -82,11 +84,13 @@ class TreeView extends React.Component<TreeViewProps> {
     private _header?: React.RefObject<HTMLDivElement> = React.createRef();
     private _treedropDisposer?: DragManager.DragDropDisposer;
     private _dref = React.createRef<HTMLDivElement>();
+
     get displayName() { return "TreeView(" + this.props.document.title + ")"; }  // this makes mobx trace() statements more descriptive
+
     get defaultExpandedView() { return this.childDocs ? this.fieldKey : StrCast(this.props.document.defaultExpandedView, "fields"); }
     @observable _overrideTreeViewOpen = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state
     set treeViewOpen(c: boolean) { if (this.props.preventTreeViewOpen) this._overrideTreeViewOpen = c; else this.props.document.treeViewOpen = c; }
-    @computed get treeViewOpen() { trace(); return (this.props.document.treeViewOpen && !this.props.preventTreeViewOpen) || this._overrideTreeViewOpen; }
+    @computed get treeViewOpen() { return (this.props.document.treeViewOpen && !this.props.preventTreeViewOpen) || this._overrideTreeViewOpen; }
     @computed get treeViewExpandedView() { return StrCast(this.props.document.treeViewExpandedView, this.defaultExpandedView); }
     @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.document.maxEmbedHeight, 300); }
     @computed get dataDoc() { return this.templateDataDoc ? this.templateDataDoc : this.props.document; }
@@ -145,11 +149,10 @@ class TreeView extends React.Component<TreeViewProps> {
     }
     onDragMove = (e: PointerEvent): void => {
         Doc.UnBrushDoc(this.dataDoc);
-        let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY);
+        let pt = [e.clientX, e.clientY]
         let rect = this._header!.current!.getBoundingClientRect();
-        let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2);
-        let before = x[1] < bounds[1];
-        let inside = x[0] > bounds[0] + 75;
+        let before = pt[1] < rect.top + rect.height / 2;
+        let inside = pt[0] > Math.min(rect.left + 75, rect.left + rect.width * .75) || (!before && this.treeViewOpen && DocListCast(this.dataDoc[this.fieldKey]).length);
         this._header!.current!.className = "treeViewItem-header";
         if (inside) this._header!.current!.className += " treeViewItem-header-inside";
         else if (before) this._header!.current!.className += " treeViewItem-header-above";
@@ -174,9 +177,9 @@ class TreeView extends React.Component<TreeViewProps> {
             TreeView.loadId = doc[Id];
             return this.props.addDocument(doc);
         })}
-        OnTab={undoBatch(() => {
+        OnTab={undoBatch((shift?: boolean) => {
             TreeView.loadId = this.dataDoc[Id];
-            this.props.indentDocument?.();
+            shift ? this.props.outdentDocument?.() : this.props.indentDocument?.();
             setTimeout(() => {  // unsetting/setting brushing for this doc will recreate & refocus this editableView after all other treeview changes have been made to the Dom (which may remove focus from this document).
                 Doc.UnBrushDoc(this.props.document);
                 Doc.BrushDoc(this.props.document);
@@ -212,11 +215,10 @@ class TreeView extends React.Component<TreeViewProps> {
 
     @undoBatch
     treeDrop = (e: Event, de: DragManager.DropEvent) => {
-        let x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y);
+        let pt = [de.x, de.y];
         let rect = this._header!.current!.getBoundingClientRect();
-        let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2);
-        let before = x[1] < bounds[1];
-        let inside = x[0] > bounds[0] + 75 || (!before && this.treeViewOpen && DocListCast(this.dataDoc[this.fieldKey]).length);
+        let before = pt[1] < rect.top + rect.height / 2;
+        let inside = pt[0] > Math.min(rect.left + 75, rect.left + rect.width * .75) || (!before && this.treeViewOpen && DocListCast(this.dataDoc[this.fieldKey]).length);
         if (de.data instanceof DragManager.LinkDragData) {
             let sourceDoc = de.data.linkSourceDocument;
             let destDoc = this.props.document;
@@ -268,7 +270,6 @@ class TreeView extends React.Component<TreeViewProps> {
     }
 
     @computed get expandedField() {
-        trace();
         let ids: { [key: string]: string } = {};
         let doc = this.props.document;
         doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
@@ -282,9 +283,9 @@ class TreeView extends React.Component<TreeViewProps> {
                 let remDoc = (doc: Doc) => this.remove(doc, key);
                 let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
                 contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] :
-                    DocListCast(contents), this.props.treeViewId, doc, undefined, key, addDoc, remDoc, this.move,
+                    DocListCast(contents), this.props.treeViewId, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move,
                     this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active,
-                    this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen,
+                    this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.hideHeaderFields, this.props.preventTreeViewOpen,
                     [...this.props.renderedIds, doc[Id]]);
             } else {
                 contentElement = <EditableView
@@ -307,7 +308,6 @@ class TreeView extends React.Component<TreeViewProps> {
     noOverlays = (doc: Doc) => ({ title: "", caption: "" });
 
     @computed get renderContent() {
-        trace();
         const expandKey = this.treeViewExpandedView === this.fieldKey ? this.fieldKey : this.treeViewExpandedView === "links" ? "links" : undefined;
         if (expandKey !== undefined) {
             let remDoc = (doc: Doc) => this.remove(doc, expandKey);
@@ -316,9 +316,9 @@ class TreeView extends React.Component<TreeViewProps> {
             return <ul key={expandKey + "more"}>
                 {!docs ? (null) :
                     TreeView.GetChildElements(docs, this.props.treeViewId, Doc.Layout(this.props.document),
-                        this.templateDataDoc, expandKey, addDoc, remDoc, this.move,
+                        this.templateDataDoc, expandKey, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move,
                         this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
-                        this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen,
+                        this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.hideHeaderFields, this.props.preventTreeViewOpen,
                         [...this.props.renderedIds, this.props.document[Id]])}
             </ul >;
         } else if (this.treeViewExpandedView === "fields") {
@@ -354,7 +354,6 @@ class TreeView extends React.Component<TreeViewProps> {
 
     @computed
     get renderBullet() {
-        trace();
         return <div className="bullet" title="view inline" onClick={action((e: React.MouseEvent) => { this.treeViewOpen = !this.treeViewOpen; e.stopPropagation(); })} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}>
             {<FontAwesomeIcon icon={!this.treeViewOpen ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down")} />}
         </div>;
@@ -394,13 +393,12 @@ class TreeView extends React.Component<TreeViewProps> {
                 }} >
                 {this.editableView("title")}
             </div >
-            {this.props.showHeaderFields() ? headerElements : (null)}
+            {this.props.hideHeaderFields() ? (null) : headerElements}
             {openRight}
         </>;
     }
 
     render() {
-        trace();
         return <div className="treeViewItem-container" ref={this.createTreeDropTarget} onContextMenu={this.onWorkspaceContextMenu}>
             <li className="collection-child">
                 <div className="treeViewItem-header" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
@@ -419,6 +417,8 @@ class TreeView extends React.Component<TreeViewProps> {
         containingCollection: Doc,
         dataDoc: Doc | undefined,
         key: string,
+        parentCollectionDoc: Doc | undefined,
+        parentPrevSibling: Doc | undefined,
         add: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean,
         remove: ((doc: Doc) => boolean),
         move: DragManager.MoveFunction,
@@ -431,7 +431,7 @@ class TreeView extends React.Component<TreeViewProps> {
         panelWidth: () => number,
         ChromeHeight: undefined | (() => number),
         renderDepth: number,
-        showHeaderFields: () => boolean,
+        hideHeaderFields: () => boolean,
         preventTreeViewOpen: boolean,
         renderedIds: string[]
     ) {
@@ -497,6 +497,15 @@ class TreeView extends React.Component<TreeViewProps> {
                     }
                 }
             };
+            let outdent = !parentCollectionDoc ? undefined : () => {
+                if (StrCast(parentCollectionDoc.layout).indexOf("fieldKey") !== -1) {
+                    let fieldKeysub = StrCast(parentCollectionDoc.layout).split("fieldKey")[1];
+                    let fieldKey = fieldKeysub.split("\"")[1];
+                    Doc.AddDocToList(parentCollectionDoc, fieldKey, child, parentPrevSibling, false);
+                    parentCollectionDoc.treeViewOpen = true;
+                    remove(child);
+                }
+            };
             let addDocument = (doc: Doc, relativeTo?: Doc, before?: boolean) => {
                 return add(doc, relativeTo ? relativeTo : docs[i], before !== undefined ? before : false);
             };
@@ -509,10 +518,12 @@ class TreeView extends React.Component<TreeViewProps> {
                 document={pair.layout}
                 dataDoc={pair.data}
                 containingCollection={containingCollection}
+                prevSibling={docs[i]}
                 treeViewId={treeViewId}
                 ruleProvider={containingCollection.isRuleProvider && pair.layout.type !== DocumentType.TEXT ? containingCollection : containingCollection.ruleProvider as Doc}
                 key={child[Id]}
                 indentDocument={indent}
+                outdentDocument={outdent}
                 renderDepth={renderDepth}
                 deleteDoc={remove}
                 addDocument={addDocument}
@@ -527,7 +538,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 outerXf={outerXf}
                 parentKey={key}
                 active={active}
-                showHeaderFields={showHeaderFields}
+                hideHeaderFields={hideHeaderFields}
                 preventTreeViewOpen={preventTreeViewOpen}
                 renderedIds={renderedIds} />;
         });
@@ -594,7 +605,6 @@ export class CollectionTreeView extends CollectionSubView(Document) {
     }
 
     render() {
-        trace();
         let dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
         let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before, false, false, false);
         let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
@@ -622,7 +632,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
                 {this.props.Document.allowClear ? this.renderClearButton : (null)}
                 <ul className="no-indent" style={{ width: "max-content" }} >
                     {
-                        TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.Document, this.props.DataDoc, this.props.fieldKey, addDoc, this.remove,
+                        TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.Document, this.props.DataDoc, this.props.fieldKey, this.props.ContainingCollectionDoc, undefined, addDoc, this.remove,
                             moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
                             this.outerXf, this.props.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => !this.props.Document.hideHeaderFields,
                             BoolCast(this.props.Document.preventTreeViewOpen), [])
diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss
index f28ca98f7..96ea4d0d6 100644
--- a/src/client/views/nodes/ImageBox.scss
+++ b/src/client/views/nodes/ImageBox.scss
@@ -7,7 +7,7 @@
     transform-origin: top left;
 }
 
-.imageBox-cont, .imageBox-cont-interactive {
+.imageBox-cont, .imageBox-cont-dragging {
     padding: 0vw;
     position: absolute;
     text-align: center;
@@ -17,10 +17,20 @@
     max-height: 100%;
     pointer-events: none;
     background:transparent;
+    img {
+        height: auto;
+        width: 100%;
+        pointer-events: all;
+    }
+    .imageBox-fader {
+        pointer-events: all;
+    }
 }
 
-.imageBox-fader {
-    pointer-events: all;
+.imageBox-cont-dragging {
+    .imageBox-fader {
+        pointer-events: none;
+    }
 }
 
 .imageBox-dot {
@@ -33,15 +43,6 @@
     background: gray;
 }
 
-.imageBox-cont img {
-    height: auto;
-    width: 100%;
-}
-
-.imageBox-cont-interactive img {
-    height: auto;
-    width: 100%;
-}
 
 #google-photos {
     transition: all 0.5s ease 0s;
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 323b05a5a..bf82da281 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -28,6 +28,7 @@ import { CollectionFreeFormView } from '../collections/collectionFreeForm/Collec
 import { documentSchema } from '../../../new_fields/documentSchemas';
 import { Id } from '../../../new_fields/FieldSymbols';
 import { TraceMobx } from '../../../new_fields/util';
+import { SelectionManager } from '../../util/SelectionManager';
 var requestImageSize = require('../../util/request-image-size');
 var path = require('path');
 const { Howl } = require('howler');
@@ -292,7 +293,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
         if (field instanceof ImageField) paths = [this.choosePath(field.url)];
         paths.push(...altpaths);
         // }
-        let interactive = InkingControl.Instance.selectedTool || !this.props.isSelected() ? "" : "-interactive";
+        let dragging = !SelectionManager.GetIsDragging() ? "" : "-dragging";
         let rotation = NumCast(this.Document.rotation, 0);
         let aspect = (rotation % 180) ? this.Document[HeightSym]() / this.Document[WidthSym]() : 1;
         let shift = (rotation % 180) ? (nativeHeight - nativeWidth / aspect) / 2 : 0;
@@ -301,38 +302,34 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
 
         !this.Document.ignoreAspect && this.resize(srcpath);
 
-        return (
-            <div className="imageBox-cont" key={this.props.Document[Id]} ref={this.createDropTarget} onContextMenu={this.specificContextMenu}>
-                <div className="imageBox-fader" >
-                    <img key={this._smallRetryCount + (this._mediumRetryCount << 4) + (this._largeRetryCount << 8)} // force cache to update on retrys
-                        src={srcpath}
-                        style={{ transform: `translate(0px, ${shift}px) rotate(${rotation}deg) scale(${aspect})` }}
+        return <div className={`imageBox-cont${dragging}`} key={this.props.Document[Id]} ref={this.createDropTarget} onContextMenu={this.specificContextMenu}>
+            <div className="imageBox-fader" >
+                <img key={this._smallRetryCount + (this._mediumRetryCount << 4) + (this._largeRetryCount << 8)} // force cache to update on retrys
+                    src={srcpath}
+                    style={{ transform: `translate(0px, ${shift}px) rotate(${rotation}deg) scale(${aspect})` }}
+                    width={nativeWidth}
+                    ref={this._imgRef}
+                    onError={this.onError} />
+                {fadepath === srcpath ? (null) : <div className="imageBox-fadeBlocker">
+                    <img className="imageBox-fadeaway"
+                        key={"fadeaway" + this._smallRetryCount + (this._mediumRetryCount << 4) + (this._largeRetryCount << 8)} // force cache to update on retrys
+                        src={fadepath}
+                        style={{ transform: `translate(0px, ${shift}px) rotate(${rotation}deg) scale(${aspect})`, }}
                         width={nativeWidth}
                         ref={this._imgRef}
-                        onError={this.onError} />
-                    {fadepath === srcpath ? (null) : <div className="imageBox-fadeBlocker" style={{height: this.props.Document[HeightSym]()}}>
-                        <img className="imageBox-fadeaway"
-                            key={"fadeaway" + this._smallRetryCount + (this._mediumRetryCount << 4) + (this._largeRetryCount << 8)} // force cache to update on retrys
-                            src={fadepath}
-                            style={{
-                                transform: `translate(0px, ${shift}px) rotate(${rotation}deg) scale(${aspect})`,
-                                height: this.props.Document[HeightSym]()
-                            }}
-                            width={nativeWidth}
-                            ref={this._imgRef}
-                            onError={this.onError} /></div>}
-                </div>
-                <div className="imageBox-audioBackground"
-                    onPointerDown={this.audioDown}
-                    onPointerEnter={this.onPointerEnter}
-                    style={{ height: `calc(${.1 * nativeHeight / nativeWidth * 100}%)` }}
-                >
-                    <FontAwesomeIcon className="imageBox-audioFont"
-                        style={{ color: [DocListCast(extensionDoc.audioAnnotations).length ? "blue" : "gray", "green", "red"][this._audioState] }} icon={!DocListCast(extensionDoc.audioAnnotations).length ? "microphone" : faFileAudio} size="sm" />
-                </div>
-                {this.considerGooglePhotosLink()}
-                <FaceRectangles document={extensionDoc} color={"#0000FF"} backgroundColor={"#0000FF"} />
-            </div>);
+                        onError={this.onError} /></div>}
+            </div>
+            <div className="imageBox-audioBackground"
+                onPointerDown={this.audioDown}
+                onPointerEnter={this.onPointerEnter}
+                style={{ height: `calc(${.1 * nativeHeight / nativeWidth * 100}%)` }}
+            >
+                <FontAwesomeIcon className="imageBox-audioFont"
+                    style={{ color: [DocListCast(extensionDoc.audioAnnotations).length ? "blue" : "gray", "green", "red"][this._audioState] }} icon={!DocListCast(extensionDoc.audioAnnotations).length ? "microphone" : faFileAudio} size="sm" />
+            </div>
+            {this.considerGooglePhotosLink()}
+            <FaceRectangles document={extensionDoc} color={"#0000FF"} backgroundColor={"#0000FF"} />
+        </div>;
     }
 
     contentFunc = () => [this.content];
-- 
cgit v1.2.3-70-g09d2

