From 4a9d6d1409327fd99c5f554caebd917a316db32b Mon Sep 17 00:00:00 2001 From: bobzel 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{"Show Lightbox of Documents"}} placement="top"> - ; -- cgit v1.2.3-70-g09d2 From 0d59f6bc23c755c4eab2503add28699f5a5b1992 Mon Sep 17 00:00:00 2001 From: bobzel 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 = 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 = 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 { - public static SavedState: Opt<{ panX: Opt, panY: Opt, scale: Opt, transition: Opt }>; - @observable static LightboxDoc: Opt; - @observable static LightboxDocTarget: Opt; - @observable static LightboxTourmap: Opt = []; // list of all tours available from the current target - @observable static LightboxDocFilters: string[] = []; - public static LightboxHistory: Opt = []; - public static LightboxFuture: Opt = []; - public static LightboxDocView: Opt; - static path: { doc: Opt, target: Opt, history: Opt, future: Opt, saved: Opt<{ panX: Opt, panY: Opt, scale: Opt, transition: Opt }> }[] = []; - @action public static SetLightboxDoc(doc: Opt, future?: Doc[]) { + @computed public static get LightboxDoc() { return this._doc; } + @observable private static _doc: Opt; + @observable private static _docTarget: Opt; + @observable private static _tourMap: Opt = []; // list of all tours available from the current target + @observable private static _docFilters: string[] = []; // filters + private static _savedState: Opt<{ panX: Opt, panY: Opt, scale: Opt, transition: Opt }>; + private static _history: Opt<{ doc: Doc, target?: Doc }[]> = []; + private static _future: Opt = []; + private static _docView: Opt; + static path: { doc: Opt, target: Opt, history: Opt<{ doc: Doc, target?: Doc }[]>, future: Opt, saved: Opt<{ panX: Opt, panY: Opt, scale: Opt, transition: Opt }> }[] = []; + @action public static SetLightboxDoc(doc: Opt, 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 { }; } 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 { ; } + 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 { } 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 { 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) :
{ height: this.lightboxHeight() }}> { - 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 { 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 { renderDepth={0} />
{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) )} ; } 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 { const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]); if (docs.length) { - LightboxView.SetLightboxDoc(targetDoc, docs); + LightboxView.SetLightboxDoc(targetDoc, undefined, docs); } }}> 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