diff options
-rw-r--r-- | src/client/util/DocumentManager.ts | 12 | ||||
-rw-r--r-- | src/client/views/collections/CollectionDockingView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 4 | ||||
-rw-r--r-- | src/client/views/linking/LinkMenuItem.tsx | 35 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 24 | ||||
-rw-r--r-- | src/client/views/nodes/LinkAnchorBox.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/LinkDocPreview.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx | 4 |
8 files changed, 33 insertions, 52 deletions
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index d7ff03344..2ca29cb7e 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -204,15 +204,9 @@ export class DocumentManager { }; findView(0); } - } else { // there's no context view so we need to create one first and try again - createViewFunc(targetDocContext); // so first we create the target, but don't pass finished because we still need to create the target - setTimeout(() => { - const finalDocView = getFirstDocView(targetDoc); - const finalDocContextView = getFirstDocView(targetDocContext); - setTimeout(() => // if not, wait a bit to see if the context can be loaded (e.g., a PDF). wait interval heurisitic tries to guess how we're animating based on what's just become visible - this.jumpToDocument(targetDoc, willZoom, createViewFunc, undefined, linkDoc, true, undefined, finished), // pass true this time for closeContextIfNotFound - finalDocView ? 0 : finalDocContextView ? 250 : 2000); // so call jump to doc again and if the doc isn't found, it will be created. - }, 0); + } else { // there's no context view so we need to create one first and try again when that finishes + createViewFunc(targetDocContext, // after creating the context, this calls the finish function that will retry looking for the target + () => this.jumpToDocument(targetDoc, willZoom, createViewFunc, undefined, linkDoc, true /* if we don't find the target, we want to get rid of the context just created */, undefined, finished)); } } } diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 699a0f966..2eaa284cc 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -21,6 +21,7 @@ import { CollectionSubView, SubCollectionViewProps } from "./CollectionSubView"; import { CollectionViewType } from './CollectionView'; import { TabDocView } from './TabDocView'; import React = require("react"); +import { stat } from 'fs'; const _global = (window /* browser */ || global /* node */) as any; @observer @@ -147,6 +148,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) { if (!pullSide && stack) { stack.addChild(docContentConfig, undefined); + stack.setActiveContentItem(stack.contentItems[stack.contentItems.length - 1]); } else { const newItemStackConfig = { type: 'stack', content: [docContentConfig] }; const newContentItem = instance._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, instance._goldenLayout); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 89e0450d7..2783011cf 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -927,7 +927,9 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P } setScaleToZoom = (doc: Doc, scale: number = 0.75) => { - this.Document[this.scaleFieldKey] = scale * Math.min(this.props.PanelWidth() / NumCast(doc._width), this.props.PanelHeight() / NumCast(doc._height)); + const pw = this.props.PanelWidth(); + const ph = this.props.PanelHeight(); + pw && ph && (this.Document[this.scaleFieldKey] = scale * Math.min(pw / NumCast(doc._width), ph / NumCast(doc._height))); } @computed get libraryPath() { return this.props.LibraryPath ? [...this.props.LibraryPath, this.props.Document] : []; } diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 055cc8d26..5e880a7ee 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -2,8 +2,8 @@ import { FontAwesomeIcon, FontAwesomeIconProps } from '@fortawesome/react-fontaw import { Tooltip } from '@material-ui/core'; import { action, observable, runInAction } from 'mobx'; import { observer } from "mobx-react"; -import { Doc, DocListCast, Opt } from '../../../fields/Doc'; -import { BoolCast, Cast, StrCast } from '../../../fields/Types'; +import { Doc, DocListCast } from '../../../fields/Doc'; +import { Cast, StrCast } from '../../../fields/Types'; import { WebField } from '../../../fields/URLField'; import { emptyFunction, setupMoveUpEvents } from '../../../Utils'; import { DocumentType } from '../../documents/DocumentTypes'; @@ -11,7 +11,7 @@ import { DocumentManager } from '../../util/DocumentManager'; import { DragManager } from '../../util/DragManager'; import { Hypothesis } from '../../util/HypothesisUtils'; import { LinkManager } from '../../util/LinkManager'; -import { undoBatch, UndoManager } from '../../util/UndoManager'; +import { undoBatch } from '../../util/UndoManager'; import { ContextMenu } from '../ContextMenu'; import { DocumentLinksButton } from '../nodes/DocumentLinksButton'; import { DocumentView } from '../nodes/DocumentView'; @@ -146,31 +146,6 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> { ContextMenu.Instance.displayMenu(e.clientX, e.clientY); } - public static followLinkClick = async (linkDoc: Doc, sourceDoc: Doc, destinationDoc: Doc, addDocTab: (doc: Doc, where: string) => void) => { - const batch = UndoManager.StartBatch("follow link click"); - const dv = DocumentManager.Instance.getFirstDocumentView(destinationDoc); - // open up target if it's not already in view ... - const createViewFunc = (doc: Doc, followLoc: string, finished: Opt<() => void>) => { - const targetFocusAfterDocFocus = () => { - const where = StrCast(destinationDoc.followLinkLocation) || followLoc; - const hackToCallFinishAfterFocus = () => { - finished && setTimeout(finished, 0); // finished() needs to be called right after hackToCallFinishAfterFocus(), but there's no callback for that so we use the hacky timeout. - return false; // we must return false here so that the zoom to the document is not reversed. If it weren't for needing to call finished(), we wouldn't need this function at all since not having it is equivalent to returning false - }; - addDocTab(doc, where); - dv?.props.focus(doc, BoolCast(destinationDoc.followLinkZoom, true), undefined, hackToCallFinishAfterFocus); // add the target and focus on it. - return where !== "inPlace"; // return true to reset the initial focus&zoom (return false for 'inPlace' since resetting the initial focus&zoom will negate the zoom into the target) - }; - if (!destinationDoc.followLinkZoom) { - targetFocusAfterDocFocus(); - } else { - // first focus & zoom onto this (the clicked document). Then execute the function to focus on the target - dv?.props.focus(destinationDoc, BoolCast(destinationDoc.followLinkZoom, true), 1, targetFocusAfterDocFocus); - } - }; - - await DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, createViewFunc, undefined, dv?.props.ContainingCollectionDoc, batch.end, undefined); - } @action public static followDefault(linkDoc: Doc, sourceDoc: Doc, destinationDoc: Doc, addDocTab: (doc: Doc, where: string) => void) { @@ -191,7 +166,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> { }); } } else { - DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, doc => addDocTab(doc, "add:right"), false); + DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, (doc, where) => addDocTab(doc, where), false); } linkDoc.linksToAnnotation && Hypothesis.scrollToAnnotation(StrCast(linkDoc.annotationId), destinationDoc); @@ -274,7 +249,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> { <div className="destination-icon-wrapper" > <FontAwesomeIcon className="destination-icon" icon={destinationIcon} size="sm" /></div> <p className="linkMenu-destination-title" - onPointerDown={() => LinkMenuItem.followLinkClick(this.props.linkDoc, this.props.sourceDoc, this.props.destinationDoc, this.props.addDocTab)}> + onPointerDown={() => DocumentView.followLinkClick(this.props.linkDoc, this.props.sourceDoc, this.props.docView.props, false, false)}> {this.props.linkDoc.linksToAnnotation && Cast(this.props.destinationDoc.data, WebField)?.url.href === this.props.linkDoc.annotationUri ? "Annotation in" : ""} {title} </p> </div> diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index d7bd75cf4..ba762d01a 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -366,7 +366,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu } else if (this.Document["onClick-rawScript"] && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) {// bcz: hack? don't edit a script if you're clicking on a scripting box itself this.props.addDocTab(DocUtils.makeCustomViewClicked(Doc.MakeAlias(this.props.Document), undefined, "onClick"), "add:right"); } else if (this.allLinks && this.Document.isLinkButton && !e.shiftKey && !e.ctrlKey) { - this.allLinks.length && this.followLinkClick(e.altKey, e.ctrlKey, e.shiftKey); + this.allLinks.length && DocumentView.followLinkClick(undefined, this.props.Document, this.props, e.shiftKey, e.altKey); } else { if ((this.layoutDoc.onDragStart || this.props.Document.rootDocument) && !(e.ctrlKey || e.button > 0)) { // onDragStart implies a button doc that we don't want to select when clicking. RootDocument & isTemplaetForField implies we're clicking on part of a template instance and we want to select the whole template, not the part stopPropagate = false; // don't stop propagation for field templates -- want the selection to propagate up to the root document of the template @@ -384,27 +384,35 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu // follows a link - if the target is on screen, it highlights/pans to it. // if the target isn't onscreen, then it will open up the target in a tab, on the right, or in place // depending on the followLinkLocation property of the source (or the link itself as a fallback); - followLinkClick = async (altKey: boolean, ctrlKey: boolean, shiftKey: boolean) => { + public static followLinkClick = async (linkDoc: Opt<Doc>, sourceDoc: Doc, docView: { + focus: (doc: Doc, willZoom: boolean, scale?: number, afterFocus?: DocFocusFunc) => void, + addDocTab: (doc: Doc, where: string, libraryPath?: Doc[]) => boolean, + ContainingCollectionDoc?: Doc + }, shiftKey: boolean, altKey: boolean) => { const batch = UndoManager.StartBatch("follow link click"); // open up target if it's not already in view ... const createViewFunc = (doc: Doc, followLoc: string, finished: Opt<() => void>) => { const targetFocusAfterDocFocus = () => { - const where = StrCast(this.Document.followLinkLocation) || followLoc; + const where = StrCast(sourceDoc.followLinkLocation) || followLoc; const hackToCallFinishAfterFocus = () => { finished && setTimeout(finished, 0); // finished() needs to be called right after hackToCallFinishAfterFocus(), but there's no callback for that so we use the hacky timeout. return false; // we must return false here so that the zoom to the document is not reversed. If it weren't for needing to call finished(), we wouldn't need this function at all since not having it is equivalent to returning false }; - this.props.addDocTab(doc, where) && this.props.focus(doc, BoolCast(this.Document.followLinkZoom, true), undefined, hackToCallFinishAfterFocus); // add the target and focus on it. - return where !== "inPlace"; // return true to reset the initial focus&zoom (return false for 'inPlace' since resetting the initial focus&zoom will negate the zoom into the target) + const addTab = docView.addDocTab(doc, where); + addTab && setTimeout(() => { + const targDocView = DocumentManager.Instance.getFirstDocumentView(doc); + targDocView?.props.focus(doc, BoolCast(sourceDoc.followLinkZoom, true), undefined, hackToCallFinishAfterFocus); + }); // add the target and focus on it. + return where !== "inPlace" || addTab; // return true to reset the initial focus&zoom (return false for 'inPlace' since resetting the initial focus&zoom will negate the zoom into the target) }; - if (!this.Document.followLinkZoom) { + if (!sourceDoc.followLinkZoom) { targetFocusAfterDocFocus(); } else { // first focus & zoom onto this (the clicked document). Then execute the function to focus on the target - this.props.focus(this.props.Document, BoolCast(this.Document.followLinkZoom, true), 1, targetFocusAfterDocFocus); + docView.focus(sourceDoc, BoolCast(sourceDoc.followLinkZoom, true), 1, targetFocusAfterDocFocus); } }; - await DocumentManager.Instance.FollowLink(undefined, this.props.Document, createViewFunc, shiftKey, this.props.ContainingCollectionDoc, batch.end, altKey ? true : undefined); + await DocumentManager.Instance.FollowLink(linkDoc, sourceDoc, createViewFunc, BoolCast(sourceDoc.followLinkZoom, true), docView.ContainingCollectionDoc, batch.end, altKey ? true : undefined); } handle1PointerDown = (e: React.TouchEvent, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>) => { diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index 10b6aa02e..ec8c43ab4 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -73,7 +73,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps, LinkAnch anchorContainerDoc && this.props.bringToFront(anchorContainerDoc, false); if (anchorContainerDoc && !this.layoutDoc.onClick && !this._isOpen) { this._timeout = setTimeout(action(() => { - DocumentManager.Instance.FollowLink(this.rootDoc, anchorContainerDoc, document => this.props.addDocTab(document, StrCast(this.layoutDoc.linkOpenLocation, "add:right")), false); + DocumentManager.Instance.FollowLink(this.rootDoc, anchorContainerDoc, (doc, where) => this.props.addDocTab(doc, where), false); this._editing = false; }), 300 - (Date.now() - this._lastTap)); } diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 234dce374..d14157c09 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -41,7 +41,7 @@ export class LinkDocPreview extends React.Component<Props> { async followDefault() { DocumentLinksButton.EditLink = undefined; LinkDocPreview.LinkInfo = undefined; - this._targetDoc ? DocumentManager.Instance.FollowLink(this.props.linkDoc, this._targetDoc, doc => this.props.addDocTab(doc, "add:right"), false) : null; + this._targetDoc ? DocumentManager.Instance.FollowLink(this.props.linkDoc, this._targetDoc, (doc, where) => this.props.addDocTab(doc, where), false) : null; } componentWillUnmount() { LinkDocPreview.TargetDoc = undefined; } diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index e482992d6..21b5190f9 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -15,9 +15,9 @@ import { DocumentType } from "../../../documents/DocumentTypes"; import { LinkManager } from "../../../util/LinkManager"; import { Transform } from "../../../util/Transform"; import { undoBatch } from "../../../util/UndoManager"; -import { LinkMenuItem } from "../../linking/LinkMenuItem"; import { ContentFittingDocumentView } from "../ContentFittingDocumentView"; import { DocumentLinksButton } from "../DocumentLinksButton"; +import { DocumentView } from "../DocumentView"; import { LinkDocPreview } from "../LinkDocPreview"; import { FormattedTextBox } from "./FormattedTextBox"; import './FormattedTextBoxComment.scss'; @@ -117,7 +117,7 @@ export class FormattedTextBoxComment { textBox.props.addDocTab(linkDoc, e.ctrlKey ? "add" : "add:right"); } else { const target = LinkManager.getOppositeAnchor(linkDoc, textBox.dataDoc); - target && LinkMenuItem.followLinkClick(linkDoc, textBox.dataDoc, target, textBox.props.addDocTab); + target && DocumentView.followLinkClick(linkDoc, textBox.dataDoc, textBox.props, e.shiftKey, e.altKey); } } } |