From 4a9d6d1409327fd99c5f554caebd917a316db32b Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 12 Feb 2021 11:00:29 -0500
Subject: changed lightbox to navigate within frame if next target is alreay
 there, otherwise create it.  changed focus default to call afterFocus(). 
 fixed bug of zooming on target doc to compute scale correctly.

---
 src/client/views/collections/CollectionMenu.tsx | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index d6e4b01c4..5fa988f06 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -489,13 +489,12 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
     @computed get lightboxButton() {
         const targetDoc = this.selectedDoc;
         return !targetDoc ? (null) : <Tooltip title={<div className="dash-tooltip">{"Show Lightbox of Documents"}</div>} placement="top">
-            <button className="antimodeMenu-button" onPointerDown={action(() => {
+            <button className="antimodeMenu-button" onPointerDown={() => {
                 const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
                 if (docs.length) {
-                    LightboxView.LightboxDoc = docs[0];
-                    LightboxView.LightboxFuture = docs.slice(1);
+                    LightboxView.SetLightboxDoc(targetDoc, docs);
                 }
-            })}>
+            }}>
                 <FontAwesomeIcon className="documentdecorations-icon" icon="desktop" size="lg" />
             </button>
         </Tooltip>;
-- 
cgit v1.2.3-70-g09d2


From 0d59f6bc23c755c4eab2503add28699f5a5b1992 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 18 Feb 2021 00:26:45 -0500
Subject: better version of forward/backward view management in lightBoxview.

---
 src/client/util/DocumentManager.ts                 |   3 +-
 src/client/views/DocumentDecorations.tsx           |   2 +-
 src/client/views/LightboxView.tsx                  | 149 ++++++++++++---------
 src/client/views/collections/CollectionMenu.tsx    |   2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   2 +-
 5 files changed, 88 insertions(+), 70 deletions(-)

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

diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index d028258b2..67e05f8d0 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -9,6 +9,7 @@ import { CollectionView } from '../views/collections/CollectionView';
 import { LightboxView } from '../views/LightboxView';
 import { DocumentView, ViewAdjustment } from '../views/nodes/DocumentView';
 import { Scripting } from './Scripting';
+import { CurrentUserUtils } from './CurrentUserUtils';
 
 export class DocumentManager {
 
@@ -102,7 +103,7 @@ export class DocumentManager {
     public getLightboxDocumentView = (toFind: Doc, originatingDoc: Opt<Doc> = undefined): DocumentView | undefined => {
         const docViews = DocumentManager.Instance.DocumentViews;
         const views: DocumentView[] = [];
-        docViews.map(view => LightboxView.IsLightboxDocView(view.docViewPath) && view.rootDoc === toFind && views.push(view));
+        docViews.map(view => LightboxView.IsLightboxDocView(view.docViewPath) && Doc.AreProtosEqual(view.rootDoc, toFind) && views.push(view));
         return views?.find(view => view.ContentDiv?.getBoundingClientRect().width && view.props.focus !== returnFalse) || views?.find(view => view.props.focus !== returnFalse) || (views.length ? views[0] : undefined);
     }
     public getFirstDocumentView = (toFind: Doc, originatingDoc: Opt<Doc> = undefined): DocumentView | undefined => {
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 87ed142f8..c8a5b338a 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -175,7 +175,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
                 } else if (e.altKey) {    // open same document in new tab
                     CollectionDockingView.ToggleSplit(Cast(selectedDocs[0].props.Document._fullScreenView, Doc, null) || selectedDocs[0].props.Document, "right");
                 } else {
-                    LightboxView.SetLightboxDoc(selectedDocs[0].props.Document, selectedDocs.slice(1).map(view => view.props.Document));
+                    LightboxView.SetLightboxDoc(selectedDocs[0].props.Document, undefined, selectedDocs.slice(1).map(view => view.props.Document));
                 }
             }
         }
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 7cfebcc3e..af07ead97 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -1,21 +1,20 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, observable, computed } from 'mobx';
+import { action, computed, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import "normalize.css";
 import * as React from 'react';
-import { Doc, Opt, DocListCast, DocListCastAsync } from '../../fields/Doc';
-import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../Utils';
-import { Transform } from '../util/Transform';
-import "./LightboxView.scss";
-import { DocumentView } from './nodes/DocumentView';
-import { DefaultStyleProvider } from './StyleProvider';
+import { Doc, DocListCast, Opt } from '../../fields/Doc';
+import { Cast, NumCast, StrCast } from '../../fields/Types';
+import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnTrue } from '../../Utils';
 import { DocUtils } from '../documents/Documents';
 import { DocumentManager } from '../util/DocumentManager';
+import { LinkManager } from '../util/LinkManager';
 import { SelectionManager } from '../util/SelectionManager';
+import { Transform } from '../util/Transform';
 import { TabDocView } from './collections/TabDocView';
-import { Cast, NumCast, StrCast } from '../../fields/Types';
-import { LinkManager } from '../util/LinkManager';
-import { List } from '../../fields/List';
+import "./LightboxView.scss";
+import { DocumentView } from './nodes/DocumentView';
+import { DefaultStyleProvider } from './StyleProvider';
 
 interface LightboxViewProps {
     PanelWidth: number;
@@ -25,27 +24,29 @@ interface LightboxViewProps {
 
 @observer
 export class LightboxView extends React.Component<LightboxViewProps> {
-    public static SavedState: Opt<{ panX: Opt<number>, panY: Opt<number>, scale: Opt<number>, transition: Opt<string> }>;
-    @observable static LightboxDoc: Opt<Doc>;
-    @observable static LightboxDocTarget: Opt<Doc>;
-    @observable static LightboxTourmap: Opt<Doc[]> = [];   // list of all tours available from the current target
-    @observable static LightboxDocFilters: string[] = [];
-    public static LightboxHistory: Opt<Doc[]> = [];
-    public static LightboxFuture: Opt<Doc[]> = [];
-    public static LightboxDocView: Opt<DocumentView>;
-    static path: { doc: Opt<Doc>, target: Opt<Doc>, history: Opt<Doc[]>, future: Opt<Doc[]>, saved: Opt<{ panX: Opt<number>, panY: Opt<number>, scale: Opt<number>, transition: Opt<string> }> }[] = [];
-    @action public static SetLightboxDoc(doc: Opt<Doc>, future?: Doc[]) {
+    @computed public static get LightboxDoc() { return this._doc; }
+    @observable private static _doc: Opt<Doc>;
+    @observable private static _docTarget: Opt<Doc>;
+    @observable private static _tourMap: Opt<Doc[]> = [];   // list of all tours available from the current target
+    @observable private static _docFilters: string[] = []; // filters
+    private static _savedState: Opt<{ panX: Opt<number>, panY: Opt<number>, scale: Opt<number>, transition: Opt<string> }>;
+    private static _history: Opt<{ doc: Doc, target?: Doc }[]> = [];
+    private static _future: Opt<Doc[]> = [];
+    private static _docView: Opt<DocumentView>;
+    static path: { doc: Opt<Doc>, target: Opt<Doc>, history: Opt<{ doc: Doc, target?: Doc }[]>, future: Opt<Doc[]>, saved: Opt<{ panX: Opt<number>, panY: Opt<number>, scale: Opt<number>, transition: Opt<string> }> }[] = [];
+    @action public static SetLightboxDoc(doc: Opt<Doc>, target?: Doc, future?: Doc[]) {
         if (!doc) {
-            LightboxView.LightboxDocFilters.length = 0;
+            this._docFilters && (this._docFilters.length = 0);
             if (this.LightboxDoc) {
-                this.LightboxDoc._panX = this.SavedState?.panX;
-                this.LightboxDoc._panY = this.SavedState?.panY;
-                this.LightboxDoc._viewScale = this.SavedState?.scale;
-                this.LightboxDoc._viewTransition = this.SavedState?.transition;
+                this.LightboxDoc._panX = this._savedState?.panX;
+                this.LightboxDoc._panY = this._savedState?.panY;
+                this.LightboxDoc._viewScale = this._savedState?.scale;
+                this.LightboxDoc._viewTransition = this._savedState?.transition;
             }
-            LightboxView.LightboxFuture = LightboxView.LightboxHistory = [];
+            this._future = this._history = [];
         } else {
-            LightboxView.SavedState = {
+            this._history ? this._history.push({ doc, target }) : this._history = [{ doc, target }];
+            this._savedState = {
                 panX: Cast(doc._panX, "number", null),
                 panY: Cast(doc._panY, "number", null),
                 scale: Cast(doc._viewScale, "number", null),
@@ -53,17 +54,18 @@ export class LightboxView extends React.Component<LightboxViewProps> {
             };
         }
         if (future) {
-            LightboxView.LightboxFuture = future.slice().sort((a, b) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow)).sort((a, b) => DocListCast(a.links).length - DocListCast(b.links).length);
+            this._future = future.slice().sort((a, b) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow)).sort((a, b) => DocListCast(a.links).length - DocListCast(b.links).length);
         }
-        LightboxView.LightboxDoc = LightboxView.LightboxDocTarget = doc;
-        LightboxView.LightboxTourmap = DocListCast(doc?.links).map(link => {
+        this._doc = doc;
+        this._docTarget = target || doc;
+        this._tourMap = DocListCast(doc?.links).map(link => {
             const opp = LinkManager.getOppositeAnchor(link, doc!);
             return opp?.TourMap ? opp : undefined;
         }).filter(m => m).map(m => m!);
 
         return true;
     }
-    public static IsLightboxDocView(path: DocumentView[]) { return path.includes(LightboxView.LightboxDocView!); }
+    public static IsLightboxDocView(path: DocumentView[]) { return path.includes(this._docView!); }
     @computed get leftBorder() { return Math.min(this.props.PanelWidth / 4, this.props.maxBorder[0]); }
     @computed get topBorder() { return Math.min(this.props.PanelHeight / 4, this.props.maxBorder[1]); }
     lightboxWidth = () => this.props.PanelWidth - this.leftBorder * 2;
@@ -83,27 +85,36 @@ export class LightboxView extends React.Component<LightboxViewProps> {
             </div>
         </div>;
     }
+    public static GetSavedState(doc: Doc) {
+        return this.LightboxDoc === doc && this._savedState ? this._savedState : undefined;
+    }
+    public static SetDocFilter(filter: string) {
+        if (this.LightboxDoc && filter) {
+            this._docFilters = [`cookies:${filter}:match`];
+        }
+    }
     public static AddDocTab = (doc: Doc, location: string) => {
         SelectionManager.DeselectAll();
-        return LightboxView.SetLightboxDoc(doc,
+        return LightboxView.SetLightboxDoc(doc, undefined,
             [...DocListCast(doc[Doc.LayoutFieldKey(doc)]),
             ...DocListCast(doc[Doc.LayoutFieldKey(doc) + "-annotations"]),
-            ...(LightboxView.LightboxFuture ?? [])
+            ...(LightboxView._future ?? [])
             ]
                 .sort((a: Doc, b: Doc) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow)));
     }
-    docFilters = () => LightboxView.LightboxDocFilters || [];
+    docFilters = () => LightboxView._docFilters || [];
     addDocTab = LightboxView.AddDocTab;
     @action
     stepForward = () => {
-        const target = LightboxView.LightboxDocTarget = LightboxView.LightboxFuture?.pop();
+        const doc = LightboxView._doc!;
+        const target = LightboxView._docTarget = LightboxView._future?.pop();
         const docView = target && DocumentManager.Instance.getLightboxDocumentView(target);
         if (docView && target) {
             docView.focus(target, { willZoom: true, scale: 0.9 });
-            if (LightboxView.LightboxHistory?.lastElement() !== target) LightboxView.LightboxHistory?.push(target);
+            if (LightboxView._history?.lastElement().target !== target) LightboxView._history?.push({ doc, target: LightboxView._docTarget });
         } else {
             if (!target && LightboxView.path.length) {
-                const saved = LightboxView.SavedState;
+                const saved = LightboxView._savedState;
                 if (LightboxView.LightboxDoc) {
                     LightboxView.LightboxDoc._panX = saved?.panX;
                     LightboxView.LightboxDoc._panY = saved?.panY;
@@ -112,34 +123,41 @@ export class LightboxView extends React.Component<LightboxViewProps> {
                 }
                 const pop = LightboxView.path.pop();
                 if (pop) {
-                    LightboxView.LightboxDoc = pop.doc;
-                    LightboxView.LightboxDocTarget = pop.target;
-                    LightboxView.LightboxFuture = pop.future;
-                    LightboxView.LightboxHistory = pop.history;
-                    LightboxView.SavedState = pop.saved;
+                    LightboxView._doc = pop.doc;
+                    LightboxView._docTarget = pop.target;
+                    LightboxView._future = pop.future;
+                    LightboxView._history = pop.history;
+                    LightboxView._savedState = pop.saved;
                 }
             } else {
                 LightboxView.SetLightboxDoc(target);
             }
         }
-        LightboxView.LightboxTourmap = DocListCast(LightboxView.LightboxDocTarget?.links).map(link => {
-            const opp = LinkManager.getOppositeAnchor(link, LightboxView.LightboxDocTarget!);
+        LightboxView._tourMap = DocListCast(LightboxView._docTarget?.links).map(link => {
+            const opp = LinkManager.getOppositeAnchor(link, LightboxView._docTarget!);
             return opp?.TourMap ? opp : undefined;
         }).filter(m => m).map(m => m!);
     }
     @action
     stepBackward = () => {
-        const previous = LightboxView.LightboxHistory?.pop();
-        const target = LightboxView.LightboxDocTarget = LightboxView.LightboxHistory?.lastElement();
+        const previous = LightboxView._history?.pop();
+        if (!previous || !LightboxView._history?.length) {
+            LightboxView.SetLightboxDoc(undefined);
+            return;
+        }
+        const { doc, target } = LightboxView._history?.lastElement()!;
         const docView = target && DocumentManager.Instance.getLightboxDocumentView(target);
         if (docView && target) {
-            if (LightboxView.LightboxFuture?.lastElement() !== previous) LightboxView.LightboxFuture?.push(previous!);
+            LightboxView._doc = doc;
+            LightboxView._docTarget = target || doc;
+            if (LightboxView._future?.lastElement() !== previous.target || previous.doc) LightboxView._future?.push(previous.target || previous.doc);
             docView.focus(target, { willZoom: true, scale: 0.9 });
         } else {
-            LightboxView.SetLightboxDoc(target);
+            LightboxView._doc = doc;
+            LightboxView._docTarget = target || doc;
         }
-        LightboxView.LightboxTourmap = DocListCast(LightboxView.LightboxDocTarget?.links).map(link => {
-            const opp = LinkManager.getOppositeAnchor(link, LightboxView.LightboxDocTarget!);
+        LightboxView._tourMap = DocListCast(LightboxView._docTarget?.links).map(link => {
+            const opp = LinkManager.getOppositeAnchor(link, LightboxView._docTarget!);
             return opp?.TourMap ? opp : undefined;
         }).filter(m => m).map(m => m!);
     }
@@ -147,29 +165,28 @@ export class LightboxView extends React.Component<LightboxViewProps> {
     stepInto = () => {
         LightboxView.path.push({
             doc: LightboxView.LightboxDoc,
-            target: LightboxView.LightboxDocTarget,
-            future: LightboxView.LightboxFuture,
-            history: LightboxView.LightboxHistory,
-            saved: LightboxView.SavedState
+            target: LightboxView._docTarget,
+            future: LightboxView._future,
+            history: LightboxView._history,
+            saved: LightboxView._savedState
         });
-        const tours = LightboxView.LightboxTourmap;
+        const tours = LightboxView._tourMap;
         if (tours && tours.length) {
             const fieldKey = Doc.LayoutFieldKey(tours[0]);
-            LightboxView.LightboxFuture?.push(...DocListCast(tours[0][fieldKey]).reverse());
+            LightboxView._future?.push(...DocListCast(tours[0][fieldKey]).reverse());
         } else {
-            const coll = LightboxView.LightboxDocTarget;
+            const coll = LightboxView._docTarget;
             if (coll) {
                 const fieldKey = Doc.LayoutFieldKey(coll);
-                LightboxView.SetLightboxDoc(coll, [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + "-annotations"])]);
+                LightboxView.SetLightboxDoc(coll, undefined, [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + "-annotations"])]);
                 TabDocView.PinDoc(coll, { hidePresBox: true });
             }
         }
         setTimeout(() => this.stepForward());
     }
 
-    fitToBox = () => LightboxView.LightboxDocTarget === LightboxView.LightboxDoc;
+    fitToBox = () => LightboxView._docTarget === LightboxView.LightboxDoc;
     render() {
-        if (LightboxView.LightboxHistory?.lastElement() !== LightboxView.LightboxDoc) LightboxView.LightboxHistory?.push(LightboxView.LightboxDoc!);
         let downx = 0, downy = 0;
         return !LightboxView.LightboxDoc ? (null) :
             <div className="lightboxView-frame"
@@ -186,7 +203,7 @@ export class LightboxView extends React.Component<LightboxViewProps> {
                     height: this.lightboxHeight()
                 }}>
                     <DocumentView ref={action((r: DocumentView | null) => {
-                        LightboxView.LightboxDocView = r !== null ? r : undefined;
+                        LightboxView._docView = r !== null ? r : undefined;
                         setTimeout(action(() => {
                             const vals = r?.ComponentView?.freeformData?.();
                             if (vals && r) {
@@ -194,7 +211,7 @@ export class LightboxView extends React.Component<LightboxViewProps> {
                                 r.layoutDoc._panY = vals.panY;
                                 r.layoutDoc._viewScale = vals.scale;
                             }
-                            LightboxView.LightboxDocTarget = undefined;
+                            r && (LightboxView._docTarget = undefined);
                         }));
                     })}
                         Document={LightboxView.LightboxDoc}
@@ -223,21 +240,21 @@ export class LightboxView extends React.Component<LightboxViewProps> {
                         renderDepth={0} />
                 </div>
                 {this.navBtn(0, undefined, this.props.PanelHeight / 2 - 12.50, "chevron-left",
-                    () => LightboxView.LightboxDoc && LightboxView.LightboxHistory?.length ? "" : "none", e => {
+                    () => LightboxView.LightboxDoc && LightboxView._history?.length ? "" : "none", e => {
                         e.stopPropagation();
                         this.stepBackward();
                     })}
                 {this.navBtn(this.props.PanelWidth - Math.min(this.props.PanelWidth / 4, this.props.maxBorder[0]), undefined, this.props.PanelHeight / 2 - 12.50, "chevron-right",
-                    () => LightboxView.LightboxDoc && LightboxView.LightboxFuture?.length ? "" : "none", e => {
+                    () => LightboxView.LightboxDoc && LightboxView._future?.length ? "" : "none", e => {
                         e.stopPropagation();
                         this.stepForward();
                     })}
                 {this.navBtn("50%", 0, 0, "chevron-down",
-                    () => LightboxView.LightboxDoc && LightboxView.LightboxFuture?.length ? "" : "none", e => {
+                    () => LightboxView.LightboxDoc && LightboxView._future?.length ? "" : "none", e => {
                         e.stopPropagation();
                         this.stepInto();
                     },
-                    StrCast(LightboxView.LightboxTourmap?.lastElement()?.TourMap)
+                    StrCast(LightboxView._tourMap?.lastElement()?.TourMap)
                 )}
             </div>;
     }
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 5fa988f06..423c94005 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -492,7 +492,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
             <button className="antimodeMenu-button" onPointerDown={() => {
                 const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
                 if (docs.length) {
-                    LightboxView.SetLightboxDoc(targetDoc, docs);
+                    LightboxView.SetLightboxDoc(targetDoc, undefined, docs);
                 }
             }}>
                 <FontAwesomeIcon className="documentdecorations-icon" icon="desktop" size="lg" />
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 3ca2258ee..58288a7b1 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -916,7 +916,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                 HistoryUtil.pushState(state);
             }
         }
-        const LightboxState = LightboxView.LightboxDoc === this.props.Document && LightboxView.SavedState ? LightboxView.SavedState : undefined;
+        const LightboxState = LightboxView.GetSavedState(this.props.Document);
         SelectionManager.DeselectAll();
         if (this.props.Document.scrollHeight) {
             this.props.focus(doc, options);
-- 
cgit v1.2.3-70-g09d2

