diff options
Diffstat (limited to 'src/client/views/nodes/DocumentView.tsx')
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 120 |
1 files changed, 70 insertions, 50 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index dc597e5ff..8df28a770 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -8,7 +8,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { Bounce, Fade, Flip, JackInTheBox, Roll, Rotate, Zoom } from 'react-awesome-reveal'; import { ClientUtils, DivWidth, isTargetChildOf as isParentOf, lightOrDark, returnFalse, returnVal, simulateMouseClick } from '../../../ClientUtils'; -import { Utils, emptyFunction, emptyPath } from '../../../Utils'; +import { Utils, emptyFunction } from '../../../Utils'; import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../fields/Doc'; import { AclAdmin, AclEdit, AclPrivate, Animation, AudioPlay, DocData, DocViews } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; @@ -35,20 +35,21 @@ import { SnappingManager } from '../../util/SnappingManager'; import { UndoManager, undoBatch, undoable } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; -import { DocComponent, ViewBoxInterface } from '../DocComponent'; +import { DocComponent } from '../DocComponent'; import { EditableView } from '../EditableView'; import { FieldsDropdown } from '../FieldsDropdown'; -import { LightboxView } from '../LightboxView'; +import { ObserverJsxParser } from '../ObservableReactComponent'; import { PinProps } from '../PinFuncs'; import { StyleProp } from '../StyleProp'; -import { DocumentContentsView, ObserverJsxParser } from './DocumentContentsView'; +import { ViewBoxInterface } from '../ViewBoxInterface'; +import { DocumentContentsView } from './DocumentContentsView'; import { DocumentLinksButton } from './DocumentLinksButton'; import './DocumentView.scss'; import { FieldViewProps, FieldViewSharedProps } from './FieldView'; import { FocusViewOptions } from './FocusViewOptions'; -import { OpenWhere } from './OpenWhere'; +import { OpenWhere, OpenWhereMod } from './OpenWhere'; import { FormattedTextBox } from './formattedText/FormattedTextBox'; -import { PresEffect, PresEffectDirection } from './trails'; +import { PresEffect, PresEffectDirection } from './trails/PresEnums'; export interface DocumentViewProps extends FieldViewSharedProps { hideDecorations?: boolean; // whether to suppress all DocumentDecorations when doc is selected @@ -77,7 +78,7 @@ export interface DocumentViewProps extends FieldViewSharedProps { dragStarting?: () => void; dragEnding?: () => void; - parent?: any; + parent?: any; // parent React component view (see CollectionFreeFormDocumentView) } @observer export class DocumentViewInternal extends DocComponent<FieldViewProps & DocumentViewProps>() { @@ -320,7 +321,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document if (this.onDoubleClickHandler?.script) { UndoManager.RunInBatch(() => this.onDoubleClickHandler.script.run(scriptProps, console.log).result?.select && this._props.select(false), 'on double click: ' + this.Document.title); } else if (!Doc.IsSystem(this.Document) && defaultDblclick !== 'ignore') { - UndoManager.RunInBatch(() => LightboxView.Instance.AddDocTab(this.Document, OpenWhere.lightbox), 'double tap'); + UndoManager.RunInBatch(() => this._props.addDocTab(this.Document, OpenWhere.lightbox), 'double tap'); DocumentView.DeselectAll(); Doc.UnBrushDoc(this.Document); } else { @@ -561,7 +562,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document const appearanceItems: ContextMenuProps[] = appearance && 'subitems' in appearance ? appearance.subitems : []; if (this._props.renderDepth === 0) { - appearanceItems.splice(0, 0, { description: 'Open in Lightbox', event: () => LightboxView.Instance.SetLightboxDoc(this.Document), icon: 'external-link-alt' }); + appearanceItems.splice(0, 0, { description: 'Open in Lightbox', event: () => DocumentView.SetLightboxDoc(this.Document), icon: 'external-link-alt' }); } appearanceItems.push({ description: 'Pin', event: () => this._props.pinToPres(this.Document, {}), icon: 'eye' }); !Doc.noviceMode && templateDoc && appearanceItems.push({ description: 'Open Template ', event: () => this._props.addDocTab(templateDoc, OpenWhere.addRight), icon: 'eye' }); @@ -980,6 +981,29 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document @observer export class DocumentView extends DocComponent<DocumentViewProps>() { public static ROOT_DIV = 'documentView-effectsWrapper'; + public static addSplit: (Doc: Doc, where: OpenWhereMod) => void; + // Lightbox + public static _lightboxDoc: () => Doc | undefined; + public static _lightboxContains: (view?: DocumentView) => boolean | undefined; + public static _setLightboxDoc: (doc: Opt<Doc>, target?: Doc, future?: Doc[], layoutTemplate?: Doc | string) => boolean; + /** + * @returns The Doc, if any, being displayed in the lightbox + */ + public static readonly LightboxDoc = () => DocumentView._lightboxDoc?.(); + /** + * @param view + * @returns whether 'view' is anywhere in the rendering hierarchy of the lightbox + */ + public static readonly LightboxContains = (view?: DocumentView) => DocumentView._lightboxContains?.(view); + /** + * Sets the root Doc to render in the lightbox view. + * @param doc + * @param target a Doc within 'doc' to focus on (useful for freeform collections) + * @param future a list of Docs to step through with the arrow buttons of the lightbox + * @param layoutTemplate a template to apply to 'doc' to render it. + * @returns success flag which is currently always true + */ + public static readonly SetLightboxDoc = (doc: Opt<Doc>, target?: Doc, future?: Doc[], layoutTemplate?: Doc | string) => DocumentView._setLightboxDoc(doc, target, future, layoutTemplate); // Sharing Manager public static ShareOpen: (target?: DocumentView, targetDoc?: Doc) => void; // LinkFollower @@ -998,6 +1022,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { public static addView: (dv: DocumentView) => void | undefined; public static removeView: (dv: DocumentView) => void | undefined; public static addViewRenderedCb: (doc: Opt<Doc>, func: (dv: DocumentView) => any) => boolean; + public static getViews = (doc?: Doc) => Array.from(doc?.[DocViews] ?? []) as DocumentView[]; public static getFirstDocumentView: (toFind: Doc) => DocumentView | undefined; public static getDocumentView: (target: Doc | undefined, preferredCollection?: DocumentView) => Opt<DocumentView>; public static getContextPath: (doc: Opt<Doc>, includeExistingViews?: boolean) => Doc[]; @@ -1032,8 +1057,8 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { public static UniquifyId(inLightbox: boolean | undefined, id: string) { return (inLightbox ? 'lightbox-' : '') + id; } - public ViewGuid = DocumentView.UniquifyId(LightboxView.Contains(this), Utils.GenerateGuid()); // a unique id associated with the main <div>. used by LinkBox's Xanchor to find the arrowhead locations. - public DocUniqueId = DocumentView.UniquifyId(LightboxView.Contains(this), this.Document[Id]); + public ViewGuid = DocumentView.UniquifyId(DocumentView.LightboxContains(this), Utils.GenerateGuid()); // a unique id associated with the main <div>. used by LinkBox's Xanchor to find the arrowhead locations. + public DocUniqueId = DocumentView.UniquifyId(DocumentView.LightboxContains(this), this.Document[Id]); constructor(props: DocumentViewProps) { super(props); @@ -1401,6 +1426,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { }}> <DocumentViewInternal {...this._props} + parent={undefined} fieldKey={this.LayoutFieldKey} DataTransition={this.DataTransition} DocumentView={this.selfView} @@ -1451,58 +1477,52 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { const docId = ClientUtils.CurrentUserEmail() + Doc.GetProto(linkAnchor)[Id] + '-pivotish'; // prettier-ignore DocServer.GetRefField(docId).then(docx => - LightboxView.Instance.SetLightboxDoc( + DocumentView.SetLightboxDoc( (docx as Doc) ?? // reuse existing pivot view of documents, or else create a new collection Docs.Create.StackingDocument([], { title: linkAnchor.title + '-pivot', _width: 500, _height: 500, target: linkAnchor, onViewMounted: ScriptField.MakeScript('updateLinkCollection(this, this.target)') }, docId) ) ); } -} - -export function returnEmptyDocViewList() { - return emptyPath; -} - -// eslint-disable-next-line default-param-last -export function DocFocusOrOpen(docIn: Doc, optionsIn: FocusViewOptions = { willZoomCentered: true, zoomScale: 0, openLocation: OpenWhere.toggleRight }, containingDoc?: Doc) { - let doc = docIn; - const options = optionsIn; - const func = () => { - const cv = DocumentView.getDocumentView(containingDoc); - const dv = DocumentView.getDocumentView(doc, cv); - if (dv && (!containingDoc || dv.containerViewPath?.().lastElement()?.Document === containingDoc)) { - DocumentView.showDocumentView(dv, options).then(() => dv && Doc.linkFollowHighlight(dv.Document)); - } else { - const container = DocCast(containingDoc ?? doc.embedContainer ?? Doc.BestEmbedding(doc)); - const showDoc = !Doc.IsSystem(container) && !cv ? container : doc; - options.toggleTarget = undefined; - DocumentView.showDocument(showDoc, options, () => DocumentView.showDocument(doc, { ...options, openLocation: undefined })).then(() => { - const cvFound = DocumentView.getDocumentView(containingDoc); - const dvFound = DocumentView.getDocumentView(doc, cvFound); - dvFound && Doc.linkFollowHighlight(dvFound.Document); - }); + // eslint-disable-next-line default-param-last + public static FocusOrOpen(docIn: Doc, optionsIn: FocusViewOptions = { willZoomCentered: true, zoomScale: 0, openLocation: OpenWhere.toggleRight }, containingDoc?: Doc) { + let doc = docIn; + const options = optionsIn; + const func = () => { + const cv = DocumentView.getDocumentView(containingDoc); + const dv = DocumentView.getDocumentView(doc, cv); + if (dv && (!containingDoc || dv.containerViewPath?.().lastElement()?.Document === containingDoc)) { + DocumentView.showDocumentView(dv, options).then(() => dv && Doc.linkFollowHighlight(dv.Document)); + } else { + const container = DocCast(containingDoc ?? doc.embedContainer ?? Doc.BestEmbedding(doc)); + const showDoc = !Doc.IsSystem(container) && !cv ? container : doc; + options.toggleTarget = undefined; + DocumentView.showDocument(showDoc, options, () => DocumentView.showDocument(doc, { ...options, openLocation: undefined })).then(() => { + const cvFound = DocumentView.getDocumentView(containingDoc); + const dvFound = DocumentView.getDocumentView(doc, cvFound); + dvFound && Doc.linkFollowHighlight(dvFound.Document); + }); + } + }; + if (Doc.IsDataProto(doc) && Doc.GetEmbeddings(doc).some(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))) { + doc = Doc.GetEmbeddings(doc).find(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))!; } - }; - if (Doc.IsDataProto(doc) && Doc.GetEmbeddings(doc).some(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))) { - doc = Doc.GetEmbeddings(doc).find(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))!; + if (doc.hidden) { + doc.hidden = false; + options.toggleTarget = false; + setTimeout(func); + } else func(); } - if (doc.hidden) { - doc.hidden = false; - options.toggleTarget = false; - setTimeout(func); - } else func(); } -ScriptingGlobals.add(DocFocusOrOpen); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function deiconifyView(documentView: DocumentView) { - documentView.iconify(); - documentView.select(false); +ScriptingGlobals.add(function DocFocusOrOpen(docIn: Doc, optionsIn?: FocusViewOptions, containingDoc?: Doc) { + return DocumentView.FocusOrOpen(docIn, optionsIn, containingDoc); }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function deiconifyViewToLightbox(documentView: DocumentView) { - LightboxView.Instance.AddDocTab(documentView.Document, OpenWhere.lightbox, 'layout'); // , 0); +ScriptingGlobals.add(function deiconifyView(documentView: DocumentView) { + documentView.iconify(); + documentView.select(false); }); // eslint-disable-next-line prefer-arrow-callback |