aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/LightboxView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/LightboxView.tsx')
-rw-r--r--src/client/views/LightboxView.tsx258
1 files changed, 162 insertions, 96 deletions
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index a1e71b5f4..99d50b4a2 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -1,7 +1,7 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
-import "normalize.css";
+import 'normalize.css';
import * as React from 'react';
import { Doc, DocListCast, Opt } from '../../fields/Doc';
import { Cast, NumCast, StrCast } from '../../fields/Types';
@@ -13,7 +13,7 @@ import { SelectionManager } from '../util/SelectionManager';
import { Transform } from '../util/Transform';
import { CollectionDockingView } from './collections/CollectionDockingView';
import { TabDocView } from './collections/TabDocView';
-import "./LightboxView.scss";
+import './LightboxView.scss';
import { DocumentView } from './nodes/DocumentView';
import { DefaultStyleProvider, wavyBorderPath } from './StyleProvider';
@@ -25,20 +25,21 @@ interface LightboxViewProps {
@observer
export class LightboxView extends React.Component<LightboxViewProps> {
-
- @computed public static get LightboxDoc() { return this._doc; }
+ @computed public static get LightboxDoc() {
+ return this._doc;
+ }
private static LightboxDocTemplate = () => LightboxView._layoutTemplate;
@observable private static _layoutTemplate: Opt<Doc>;
@observable private static _doc: Opt<Doc>;
@observable private static _docTarget: Opt<Doc>;
@observable private static _docFilters: string[] = []; // filters
- @observable private static _tourMap: Opt<Doc[]> = []; // list of all tours available from the current target
- private static _savedState: Opt<{ panX: Opt<number>, panY: Opt<number>, scale: Opt<number>, scrollTop: Opt<number> }>;
- private static _history: Opt<{ doc: Doc, target?: Doc }[]> = [];
+ @observable private static _tourMap: Opt<Doc[]> = []; // list of all tours available from the current target
+ private static _savedState: Opt<{ panX: Opt<number>; panY: Opt<number>; scale: Opt<number>; scrollTop: Opt<number> }>;
+ private static _history: Opt<{ doc: Doc; target?: Doc }[]> = [];
@observable private static _future: Opt<Doc[]> = [];
private static _docView: Opt<DocumentView>;
private static openInTabFunc: any;
- 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>, scrollTop: Opt<number> }> }[] = [];
+ 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>; scrollTop: Opt<number> }> }[] = [];
@action public static SetLightboxDoc(doc: Opt<Doc>, target?: Doc, future?: Doc[], layoutTemplate?: Doc) {
if (this.LightboxDoc && this.LightboxDoc !== doc && this._savedState) {
this.LightboxDoc._panX = this._savedState.panX;
@@ -53,52 +54,71 @@ export class LightboxView extends React.Component<LightboxViewProps> {
} else {
if (doc) {
const l = DocUtils.MakeLinkToActiveAudio(() => doc).lastElement();
- l && (Cast(l.anchor2, Doc, null).backgroundColor = "lightgreen");
+ l && (Cast(l.anchor2, Doc, null).backgroundColor = 'lightgreen');
}
//TabDocView.PinDoc(doc, { hidePresBox: true });
- this._history ? this._history.push({ doc, target }) : this._history = [{ doc, target }];
+ this._history ? this._history.push({ doc, target }) : (this._history = [{ doc, target }]);
if (doc !== LightboxView.LightboxDoc) {
this._savedState = {
- panX: Cast(doc._panX, "number", null),
- panY: Cast(doc._panY, "number", null),
- scale: Cast(doc._viewScale, "number", null),
- scrollTop: Cast(doc._scrollTop, "number", null),
+ panX: Cast(doc._panX, 'number', null),
+ panY: Cast(doc._panY, 'number', null),
+ scale: Cast(doc._viewScale, 'number', null),
+ scrollTop: Cast(doc._scrollTop, 'number', null),
};
}
}
if (future) {
- this._future = [...(this._future ?? []), ...(this.LightboxDoc ? [this.LightboxDoc] : []), ...future.slice().sort((a, b) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow)).sort((a, b) => DocListCast(a.links).length - DocListCast(b.links).length),];
+ this._future = [
+ ...(this._future ?? []),
+ ...(this.LightboxDoc ? [this.LightboxDoc] : []),
+ ...future
+ .slice()
+ .sort((a, b) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow))
+ .sort((a, b) => DocListCast(a.links).length - DocListCast(b.links).length),
+ ];
}
this._doc = doc;
this._layoutTemplate = layoutTemplate;
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!);
+ 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(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]); }
+ 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;
lightboxHeight = () => this.props.PanelHeight - this.topBorder * 2;
lightboxScreenToLocal = () => new Transform(-this.leftBorder, -this.topBorder, 1);
navBtn = (left: Opt<string | number>, bottom: Opt<number>, top: number, icon: string, display: () => string, click: (e: React.MouseEvent) => void, color?: string) => {
- return <div className="lightboxView-navBtn-frame" style={{
- display: display(),
- left,
- width: bottom !== undefined ? undefined : Math.min(this.props.PanelWidth / 4, this.props.maxBorder[0]),
- bottom
- }}>
- <div className="lightboxView-navBtn" title={color} style={{ top, color: color ? "red" : "white", background: color ? "white" : undefined }}
- onClick={click}>
- <div style={{ height: 10 }}>{color}</div>
- <FontAwesomeIcon icon={icon as any} size="3x" />
+ return (
+ <div
+ className="lightboxView-navBtn-frame"
+ style={{
+ display: display(),
+ left,
+ width: bottom !== undefined ? undefined : Math.min(this.props.PanelWidth / 4, this.props.maxBorder[0]),
+ bottom,
+ }}>
+ <div className="lightboxView-navBtn" title={color} style={{ top, color: color ? 'red' : 'white', background: color ? 'white' : undefined }} onClick={click}>
+ <div style={{ height: 10 }}>{color}</div>
+ <FontAwesomeIcon icon={icon as any} size="3x" />
+ </div>
</div>
- </div>;
- }
+ );
+ };
public static GetSavedState(doc: Doc) {
return this.LightboxDoc === doc && this._savedState ? this._savedState : undefined;
}
@@ -107,27 +127,28 @@ export class LightboxView extends React.Component<LightboxViewProps> {
@action
public static SetCookie(cookie: string) {
if (this.LightboxDoc && cookie) {
- this._docFilters = (f => this._docFilters ? [this._docFilters.push(f) as any, this._docFilters][1] : [f])(`cookies:${cookie}:provide`);
+ this._docFilters = (f => (this._docFilters ? [this._docFilters.push(f) as any, this._docFilters][1] : [f]))(`cookies:${cookie}:provide`);
}
}
public static AddDocTab = (doc: Doc, location: string, layoutTemplate?: Doc, openInTabFunc?: any) => {
LightboxView.openInTabFunc = openInTabFunc;
SelectionManager.DeselectAll();
- return LightboxView.SetLightboxDoc(doc, undefined,
- [...DocListCast(doc[Doc.LayoutFieldKey(doc)]),
- ...DocListCast(doc[Doc.LayoutFieldKey(doc) + "-annotations"]),
- ...(LightboxView._future ?? [])
- ].sort((a: Doc, b: Doc) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow)), layoutTemplate);
- }
+ return LightboxView.SetLightboxDoc(
+ doc,
+ undefined,
+ [...DocListCast(doc[Doc.LayoutFieldKey(doc)]), ...DocListCast(doc[Doc.LayoutFieldKey(doc) + '-annotations']), ...(LightboxView._future ?? [])].sort((a: Doc, b: Doc) => NumCast(b._timecodeToShow) - NumCast(a._timecodeToShow)),
+ layoutTemplate
+ );
+ };
docFilters = () => LightboxView._docFilters || [];
addDocTab = LightboxView.AddDocTab;
@action public static Next() {
const doc = LightboxView._doc!;
- const target = LightboxView._docTarget = this._future?.pop();
+ const target = (LightboxView._docTarget = this._future?.pop());
const targetDocView = target && DocumentManager.Instance.getLightboxDocumentView(target);
if (targetDocView && target) {
const l = DocUtils.MakeLinkToActiveAudio(() => targetDocView.ComponentView?.getAnchor?.() || target).lastElement();
- l && (Cast(l.anchor2, Doc, null).backgroundColor = "lightgreen");
+ l && (Cast(l.anchor2, Doc, null).backgroundColor = 'lightgreen');
targetDocView.focus(target, { originalTarget: target, willZoom: true, scale: 0.9 });
if (LightboxView._history?.lastElement().target !== target) LightboxView._history?.push({ doc, target });
} else {
@@ -152,10 +173,13 @@ export class LightboxView extends React.Component<LightboxViewProps> {
LightboxView.SetLightboxDoc(target);
}
}
- 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!);
+ 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 public static Previous() {
@@ -170,15 +194,17 @@ export class LightboxView extends React.Component<LightboxViewProps> {
LightboxView._docTarget = target;
if (!target) docView.ComponentView?.shrinkWrap?.();
else docView.focus(target, { willZoom: true, scale: 0.9 });
- }
- else {
+ } else {
LightboxView.SetLightboxDoc(doc, target);
}
if (LightboxView._future?.lastElement() !== previous.target || previous.doc) LightboxView._future?.push(previous.target || previous.doc);
- 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!);
+ 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
stepInto = () => {
@@ -187,7 +213,7 @@ export class LightboxView extends React.Component<LightboxViewProps> {
target: LightboxView._docTarget,
future: LightboxView._future,
history: LightboxView._history,
- saved: LightboxView._savedState
+ saved: LightboxView._savedState,
});
const tours = LightboxView._tourMap;
if (tours && tours.length) {
@@ -197,45 +223,58 @@ export class LightboxView extends React.Component<LightboxViewProps> {
const coll = LightboxView._docTarget;
if (coll) {
const fieldKey = Doc.LayoutFieldKey(coll);
- const contents = [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + "-annotations"])];
- const links = DocListCast(coll.links).map(link => LinkManager.getOppositeAnchor(link, coll)).filter(doc => doc).map(doc => doc!);
+ const contents = [...DocListCast(coll[fieldKey]), ...DocListCast(coll[fieldKey + '-annotations'])];
+ const links = DocListCast(coll.links)
+ .map(link => LinkManager.getOppositeAnchor(link, coll))
+ .filter(doc => doc)
+ .map(doc => doc!);
LightboxView.SetLightboxDoc(coll, undefined, contents.length ? contents : links);
TabDocView.PinDoc(coll, { hidePresBox: true });
}
}
- }
+ };
future = () => LightboxView._future;
tourMap = () => LightboxView._tourMap;
render() {
- let downx = 0, downy = 0;
- return !LightboxView.LightboxDoc ? (null) :
- <div className="lightboxView-frame"
- onPointerDown={e => { downx = e.clientX; downy = e.clientY; }}
+ let downx = 0,
+ downy = 0;
+ return !LightboxView.LightboxDoc ? null : (
+ <div
+ className="lightboxView-frame"
+ onPointerDown={e => {
+ downx = e.clientX;
+ downy = e.clientY;
+ }}
onClick={e => {
if (Math.abs(downx - e.clientX) < 4 && Math.abs(downy - e.clientY) < 4) {
LightboxView.SetLightboxDoc(undefined);
}
- }} >
-
- <div className="lightboxView-contents" style={{
- left: this.leftBorder,
- top: this.topBorder,
- width: this.lightboxWidth(),
- height: this.lightboxHeight(),
- clipPath: `path('${Doc.UserDoc().renderStyle === "comic" ? wavyBorderPath(this.lightboxWidth(), this.lightboxHeight()) : undefined}')`
}}>
+ <div
+ className="lightboxView-contents"
+ style={{
+ left: this.leftBorder,
+ top: this.topBorder,
+ width: this.lightboxWidth(),
+ height: this.lightboxHeight(),
+ clipPath: `path('${Doc.UserDoc().renderStyle === 'comic' ? wavyBorderPath(this.lightboxWidth(), this.lightboxHeight()) : undefined}')`,
+ }}>
{/* <CollectionMenu /> TODO:glr This is where it would go*/}
- <DocumentView ref={action((r: DocumentView | null) => {
- LightboxView._docView = r !== null ? r : undefined;
- r && setTimeout(action(() => {
- const target = LightboxView._docTarget;
- const doc = LightboxView._doc;
- const targetView = target && DocumentManager.Instance.getLightboxDocumentView(target);
- if (doc === r.props.Document && (!target || target === doc)) r.ComponentView?.shrinkWrap?.();
- //else target?.focus(target, { willZoom: true, scale: 0.9, instant: true }); // bcz: why was this here? it breaks smooth navigation in lightbox using 'next' button
- }));
- })}
+ <DocumentView
+ ref={action((r: DocumentView | null) => {
+ LightboxView._docView = r !== null ? r : undefined;
+ r &&
+ setTimeout(
+ action(() => {
+ const target = LightboxView._docTarget;
+ const doc = LightboxView._doc;
+ const targetView = target && DocumentManager.Instance.getLightboxDocumentView(target);
+ if (doc === r.props.Document && (!target || target === doc)) r.ComponentView?.shrinkWrap?.();
+ //else target?.focus(target, { willZoom: true, scale: 0.9, instant: true }); // bcz: why was this here? it breaks smooth navigation in lightbox using 'next' button
+ })
+ );
+ })}
Document={LightboxView.LightboxDoc}
DataDoc={undefined}
LayoutTemplate={LightboxView.LightboxDocTemplate}
@@ -259,35 +298,57 @@ export class LightboxView extends React.Component<LightboxViewProps> {
searchFilterDocs={returnEmptyDoclist}
ContainingCollectionView={undefined}
ContainingCollectionDoc={undefined}
- renderDepth={0} />
+ renderDepth={0}
+ />
</div>
- {this.navBtn(0, undefined, this.props.PanelHeight / 2 - 12.50, "chevron-left",
- () => LightboxView.LightboxDoc && LightboxView._history?.length ? "" : "none", e => {
+ {this.navBtn(
+ 0,
+ undefined,
+ this.props.PanelHeight / 2 - 12.5,
+ 'chevron-left',
+ () => (LightboxView.LightboxDoc && LightboxView._history?.length ? '' : 'none'),
+ e => {
e.stopPropagation();
LightboxView.Previous();
- })}
- {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._future?.length ? "" : "none", e => {
+ }
+ )}
+ {this.navBtn(
+ this.props.PanelWidth - Math.min(this.props.PanelWidth / 4, this.props.maxBorder[0]),
+ undefined,
+ this.props.PanelHeight / 2 - 12.5,
+ 'chevron-right',
+ () => (LightboxView.LightboxDoc && LightboxView._future?.length ? '' : 'none'),
+ e => {
e.stopPropagation();
LightboxView.Next();
- }, this.future()?.length.toString())}
+ },
+ this.future()?.length.toString()
+ )}
<LightboxTourBtn navBtn={this.navBtn} future={this.future} stepInto={this.stepInto} tourMap={this.tourMap} />
- <div className="lightboxView-tabBtn" title={"open in tab"}
+ <div
+ className="lightboxView-tabBtn"
+ title={'open in tab'}
onClick={e => {
e.stopPropagation();
- CollectionDockingView.AddSplit(LightboxView._docTarget || LightboxView._doc!, "");
+ CollectionDockingView.AddSplit(LightboxView._docTarget || LightboxView._doc!, '');
//LightboxView.openInTabFunc(LightboxView._docTarget || LightboxView._doc!, "inPlace");
SelectionManager.DeselectAll();
LightboxView.SetLightboxDoc(undefined);
}}>
- <FontAwesomeIcon icon={"file-download"} size="2x" />
+ <FontAwesomeIcon icon={'file-download'} size="2x" />
</div>
- <div className="lightboxView-navBtn" title={"toggle fit width"}
- onClick={e => { e.stopPropagation(); LightboxView.LightboxDoc!._fitWidth = !LightboxView.LightboxDoc!._fitWidth; }}>
- <FontAwesomeIcon icon={LightboxView.LightboxDoc?._fitWidth ? "arrows-alt-h" : "arrows-alt-v"} size="2x" />
+ <div
+ className="lightboxView-navBtn"
+ title={'toggle fit width'}
+ onClick={e => {
+ e.stopPropagation();
+ LightboxView.LightboxDoc!._fitWidth = !LightboxView.LightboxDoc!._fitWidth;
+ }}>
+ <FontAwesomeIcon icon={LightboxView.LightboxDoc?._fitWidth ? 'arrows-alt-h' : 'arrows-alt-v'} size="2x" />
</div>
- </div>;
+ </div>
+ );
}
}
interface LightboxTourBtnProps {
@@ -299,12 +360,17 @@ interface LightboxTourBtnProps {
@observer
export class LightboxTourBtn extends React.Component<LightboxTourBtnProps> {
render() {
- return this.props.navBtn("50%", 0, 0, "chevron-down",
- () => LightboxView.LightboxDoc /*&& this.props.future()?.length*/ ? "" : "none", e => {
+ return this.props.navBtn(
+ '50%',
+ 0,
+ 0,
+ 'chevron-down',
+ () => (LightboxView.LightboxDoc /*&& this.props.future()?.length*/ ? '' : 'none'),
+ e => {
e.stopPropagation();
this.props.stepInto();
},
StrCast(this.props.tourMap()?.lastElement()?.TourMap)
);
}
-} \ No newline at end of file
+}