aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts5
-rw-r--r--src/client/util/LinkFollower.ts11
-rw-r--r--src/client/views/DocumentButtonBar.scss31
-rw-r--r--src/client/views/DocumentButtonBar.tsx60
-rw-r--r--src/client/views/DocumentDecorations.tsx19
-rw-r--r--src/client/views/PropertiesButtons.tsx17
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
-rw-r--r--src/client/views/linking/LinkEditor.tsx1
-rw-r--r--src/client/views/nodes/DocumentView.tsx3
-rw-r--r--src/client/views/nodes/ImageBox.tsx52
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx3
11 files changed, 154 insertions, 50 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index e44004f45..8f45802fe 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -257,6 +257,7 @@ export class DocumentOptions {
lastFrame?: number; // the last frame of a frame-based collection (e.g., progressive slide)
activeFrame?: number; // the active frame of a document in a frame base collection
appearFrame?: number; // the frame in which the document appears
+ viewTransitionTime?: number; // transition duration for view parameters
presTransition?: number; //the time taken for the transition TO a document
presDuration?: number; //the duration of the slide in presentation view
borderRounding?: string;
@@ -1047,6 +1048,10 @@ export namespace Docs {
return InstanceFromProto(Prototypes.get(DocumentType.MARKER), options?.data, options, id);
}
+ export function ImageanchorDocument(options: DocumentOptions = {}, id?: string) {
+ return InstanceFromProto(Prototypes.get(DocumentType.MARKER), options?.data, options, id);
+ }
+
export function HTMLAnchorDocument(documents: Array<Doc>, options: DocumentOptions, id?: string) {
return InstanceFromProto(Prototypes.get(DocumentType.MARKER), new List(documents), options, id);
}
diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts
index c09c9d1c5..c6fc7b372 100644
--- a/src/client/util/LinkFollower.ts
+++ b/src/client/util/LinkFollower.ts
@@ -1,6 +1,7 @@
import { action, runInAction } from 'mobx';
import { Doc, DocListCast, Opt } from '../../fields/Doc';
-import { BoolCast, Cast, StrCast } from '../../fields/Types';
+import { BoolCast, Cast, DocCast, StrCast } from '../../fields/Types';
+import { DocumentType } from '../documents/DocumentTypes';
import { DocumentDecorations } from '../views/DocumentDecorations';
import { LightboxView } from '../views/LightboxView';
import { DocumentViewSharedProps, ViewAdjustment } from '../views/nodes/DocumentView';
@@ -76,11 +77,11 @@ export class LinkFollower {
const linkDocs = link ? [link] : DocListCast(sourceDoc.links);
const firstDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor1 as Doc, sourceDoc) || Doc.AreProtosEqual((linkDoc.anchor1 as Doc).annotationOn as Doc, sourceDoc)); // link docs where 'doc' is anchor1
const secondDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor2 as Doc, sourceDoc) || Doc.AreProtosEqual((linkDoc.anchor2 as Doc).annotationOn as Doc, sourceDoc)); // link docs where 'doc' is anchor2
- const fwdLinkWithoutTargetView = firstDocs.find(d => DocumentManager.Instance.getDocumentViews(d.anchor2 as Doc).length === 0);
- const backLinkWithoutTargetView = secondDocs.find(d => DocumentManager.Instance.getDocumentViews(d.anchor1 as Doc).length === 0);
+ const fwdLinkWithoutTargetView = firstDocs.find(d => DocumentManager.Instance.getDocumentViews((d.anchor2 as Doc).type === DocumentType.MARKER ? DocCast((d.anchor2 as Doc).annotationOn) : (d.anchor2 as Doc)).length === 0);
+ const backLinkWithoutTargetView = secondDocs.find(d => DocumentManager.Instance.getDocumentViews((d.anchor1 as Doc).type === DocumentType.MARKER ? DocCast((d.anchor1 as Doc).annotationOn) : (d.anchor1 as Doc)).length === 0);
const linkWithoutTargetDoc = traverseBacklink === undefined ? fwdLinkWithoutTargetView || backLinkWithoutTargetView : traverseBacklink ? backLinkWithoutTargetView : fwdLinkWithoutTargetView;
- const linkDocList = linkWithoutTargetDoc ? [linkWithoutTargetDoc] : traverseBacklink === undefined ? firstDocs.concat(secondDocs) : traverseBacklink ? secondDocs : firstDocs;
- const followLinks = sourceDoc.isPushpin ? linkDocList : linkDocList.slice(0, 1);
+ const linkDocList = linkWithoutTargetDoc && !sourceDoc.followAllLinks ? [linkWithoutTargetDoc] : traverseBacklink === undefined ? firstDocs.concat(secondDocs) : traverseBacklink ? secondDocs : firstDocs;
+ const followLinks = sourceDoc.isPushpin || sourceDoc.followAllLinks ? linkDocList : linkDocList.slice(0, 1);
var count = 0;
const allFinished = () => ++count === followLinks.length && finished?.();
followLinks.forEach(async linkDoc => {
diff --git a/src/client/views/DocumentButtonBar.scss b/src/client/views/DocumentButtonBar.scss
index 1e93ba5e2..f9c988fdd 100644
--- a/src/client/views/DocumentButtonBar.scss
+++ b/src/client/views/DocumentButtonBar.scss
@@ -18,15 +18,44 @@ $linkGap: 3px;
cursor: pointer;
}
+.documentButtonBar-followTypes,
.documentButtonBar-pinTypes {
position: absolute;
- display: flex;
+ display: none;
width: 60px;
top: -14px;
background: black;
height: 20px;
align-items: center;
}
+.documentButtonBar-followTypes {
+ width: 20px;
+ display: none;
+}
+.documentButtonBar-followIcon {
+ align-items: center;
+ display: flex;
+ height: 100%;
+ &:hover {
+ background-color: lightblue;
+ }
+}
+.documentButtonBar-follow {
+ &:hover {
+ .documentButtonBar-followTypes {
+ display: flex;
+ }
+ }
+}
+.documentButtonBar-pin {
+ color: white;
+ &:hover {
+ .documentButtonBar-pinTypes {
+ display: flex;
+ }
+ }
+}
+
.documentButtonBar-pinIcon {
&:hover {
background-color: lightblue;
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 36875290e..794b51cc5 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -5,7 +5,7 @@ import { action, computed, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { Doc } from '../../fields/Doc';
import { RichTextField } from '../../fields/RichTextField';
-import { Cast, NumCast } from '../../fields/Types';
+import { BoolCast, Cast, NumCast } from '../../fields/Types';
import { emptyFunction, returnFalse, setupMoveUpEvents, simulateMouseClick } from '../../Utils';
import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
@@ -209,21 +209,52 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
</Tooltip>
);
}
+ @observable subFollow = '';
@computed
get followLinkButton() {
const targetDoc = this.view0?.props.Document;
+ const followBtn = (allDocs: boolean, click: (doc: Doc) => void, isSet: (doc?: Doc) => boolean, icon: IconProp) => {
+ const tooltip = `Follow ${this.subPin}documents`;
+ return !tooltip ? null : (
+ <Tooltip title={<div className="dash-tooltip">{tooltip}</div>}>
+ <div className="documentButtonBar-followIcon" style={{ backgroundColor: isSet(targetDoc) ? Colors.LIGHT_BLUE : Colors.DARK_GRAY, color: isSet(targetDoc) ? Colors.BLACK : Colors.WHITE }}>
+ <FontAwesomeIcon
+ className="documentdecorations-icon"
+ style={{ width: 20 }}
+ key={icon.toString()}
+ size="sm"
+ icon={icon}
+ onPointerEnter={action(e => (this.subPin = allDocs ? 'All ' : ''))}
+ onPointerLeave={action(e => (this.subPin = ''))}
+ onClick={e => {
+ this.props.views().forEach(dv => click(dv!.rootDoc));
+ e.stopPropagation();
+ }}
+ />
+ </div>
+ </Tooltip>
+ );
+ };
return !targetDoc ? null : (
- <Tooltip title={<div className="dash-tooltip">{'Set onClick to follow primary link'}</div>}>
+ <Tooltip title={<div className="dash-tooltip">Set onClick to follow primary link</div>}>
<div
- className="documentButtonBar-icon"
+ className="documentButtonBar-icon documentButtonBar-follow"
style={{ backgroundColor: targetDoc.isLinkButton ? Colors.LIGHT_BLUE : Colors.DARK_GRAY, color: targetDoc.isLinkButton ? Colors.BLACK : Colors.WHITE }}
onClick={undoBatch(e => this.props.views().map(view => view?.docView?.toggleFollowLink(undefined, undefined, false)))}>
+ <div className="documentButtonBar-followTypes">
+ {followBtn(
+ true,
+ (doc: Doc) => (doc.followAllLinks = !doc.followAllLinks),
+ (doc?: Doc) => (doc?.followAllLinks ? true : false),
+ 'window-maximize'
+ )}
+ </div>
<FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="hand-point-right" />
</div>
</Tooltip>
);
}
- @observable expandPin = false;
+
@observable subPin = '';
@computed
get pinButton() {
@@ -264,10 +295,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
return !targetDoc ? null : (
<Tooltip title={<div className="dash-tooltip">{`Pin Document ${SelectionManager.Views().length > 1 ? 'multiple documents' : ''} to Trail`}</div>}>
<div
- className="documentButtonBar-icon"
- style={{ color: 'white' }}
- onPointerEnter={action(e => (this.expandPin = true))}
- onPointerLeave={action(e => (this.expandPin = false))}
+ className="documentButtonBar-icon documentButtonBar-pin"
onClick={e => {
const docs = this.props
.views()
@@ -276,13 +304,11 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
TabDocView.PinDoc(docs, { pinDocLayout: e.shiftKey, pinDocContent: e.altKey, activeFrame: Cast(docs.lastElement()?.activeFrame, 'number', null) });
e.stopPropagation();
}}>
- {this.expandPin ? (
- <div className="documentButtonBar-pinTypes">
- {pinBtn(true, false, 'window-maximize')}
- {pinBtn(false, true, 'address-card')}
- {pinBtn(true, true, 'id-card')}
- </div>
- ) : null}
+ <div className="documentButtonBar-pinTypes">
+ {pinBtn(true, false, 'window-maximize')}
+ {pinBtn(false, true, 'address-card')}
+ {pinBtn(true, true, 'id-card')}
+ </div>
<FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin" />
</div>
</Tooltip>
@@ -460,9 +486,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
) : null}
{
Doc.noviceMode ? null : <div className="documentButtonBar-button">{this.templateButton}</div>
- /*<div className="documentButtonBar-button">
- {this.metadataButton}
- </div> */
+ /*<div className="documentButtonBar-button"> {this.metadataButton} </div> */
}
{Doc.noviceMode || !SelectionManager.Views()?.some(v => v.allLinks.length) ? null : <div className="documentButtonBar-button">{this.followLinkButton}</div>}
<div className="documentButtonBar-button">{this.pinButton}</div>
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 3fac137fe..3efb5fb37 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -708,24 +708,25 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
}
render() {
- const { b, c, r, x, y } = this.Bounds;
- const bounds = { b, c, r, x, y };
+ const { b, r, x, y } = this.Bounds;
+ const bounds = { b, r, x, y };
const seldocview = SelectionManager.Views().slice(-1)[0];
if (SnappingManager.GetIsDragging() || bounds.r - bounds.x < 1 || bounds.x === Number.MAX_VALUE || !seldocview || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) {
return null;
}
// hide the decorations if the parent chooses to hide it or if the document itself hides it
- const hideResizers = seldocview.props.hideResizeHandles || seldocview.rootDoc.hideResizeHandles || seldocview.rootDoc._isGroup || this._isRounding || this._isRotating;
- const hideTitle = seldocview.props.hideDecorationTitle || seldocview.rootDoc.hideDecorationTitle || this._isRounding || this._isRotating;
- const hideDocumentButtonBar = seldocview.props.hideDocumentButtonBar || seldocview.rootDoc.hideDocumentButtonBar || this._isRounding || this._isRotating;
+ const hideDecorations = seldocview.props.hideDecorations || seldocview.rootDoc.hideDecorations;
+ const hideResizers = hideDecorations || seldocview.props.hideResizeHandles || seldocview.rootDoc.hideResizeHandles || seldocview.rootDoc._isGroup || this._isRounding || this._isRotating;
+ const hideTitle = hideDecorations || seldocview.props.hideDecorationTitle || seldocview.rootDoc.hideDecorationTitle || this._isRounding || this._isRotating;
+ const hideDocumentButtonBar = hideDecorations || seldocview.props.hideDocumentButtonBar || seldocview.rootDoc.hideDocumentButtonBar || this._isRounding || this._isRotating;
// if multiple documents have been opened at the same time, then don't show open button
- const hideOpenButton =
+ const hideOpenButton =hideDecorations ||
seldocview.props.hideOpenButton ||
seldocview.rootDoc.hideOpenButton ||
SelectionManager.Views().some(docView => docView.props.Document._stayInCollection || docView.props.Document.isGroup || docView.props.Document.hideOpenButton) ||
this._isRounding ||
this._isRotating;
- const hideDeleteButton =
+ const hideDeleteButton =hideDecorations ||
this._isRounding ||
this._isRotating ||
seldocview.props.hideDeleteButton ||
@@ -767,7 +768,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
bounds.b = Math.max(bounds.y, Math.max(topBounds, Math.min(window.innerHeight, bounds.b + this._resizeBorderWidth / 2 + this._linkBoxHeight) - this._resizeBorderWidth / 2 - this._linkBoxHeight));
const useLock = bounds.r - bounds.x > 135 && seldocview.props.CollectionFreeFormDocumentView;
- const useRotation = seldocview.rootDoc.type !== DocumentType.EQUATION && seldocview.props.CollectionFreeFormDocumentView; // when do we want an object to not rotate?
+ const useRotation = !hideResizers && seldocview.rootDoc.type !== DocumentType.EQUATION && seldocview.props.CollectionFreeFormDocumentView; // when do we want an object to not rotate?
const rotation = NumCast(seldocview.rootDoc._rotation);
const resizerScheme = colorScheme ? 'documentDecorations-resizer' + colorScheme : '';
@@ -837,7 +838,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
<div className="documentDecorations-topbar" onPointerDown={this.onContainerDown}>
{hideDeleteButton ? <div /> : topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')}
{hideResizers || hideDeleteButton ? <div /> : topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')}
- {titleArea}
+ {hideTitle ? null : titleArea}
{hideOpenButton ? <div /> : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Lightbox (ctrl: as alias, shift: in new collection)')}
</div>
{hideResizers ? null : (
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 5992b3eb9..d27848a90 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -121,15 +121,24 @@ export class PropertiesButtons extends React.Component<{}, {}> {
onClick => {
SelectionManager.Views().forEach(dv => {
const containerDoc = dv.rootDoc;
- containerDoc.noShadow = containerDoc.noHighlighting = containerDoc._isLinkButton = containerDoc._fitContentsToBox = containerDoc._forceActive = containerDoc._isInPlaceContainer = !containerDoc._isInPlaceContainer;
+ containerDoc.followAllLinks =
+ containerDoc.noShadow =
+ containerDoc.noHighlighting =
+ containerDoc._isLinkButton =
+ containerDoc._fitContentsToBox =
+ containerDoc._forceActive =
+ containerDoc._isInPlaceContainer =
+ !containerDoc._isInPlaceContainer;
containerDoc.followLinkLocation = containerDoc._isInPlaceContainer ? 'inPlace' : undefined;
containerDoc._xPadding = containerDoc._yPadding = containerDoc._isInPlaceContainer ? 10 : undefined;
const menuDoc = DocListCast(dv.dataDoc[dv.props.fieldKey ?? Doc.LayoutFieldKey(containerDoc)]).lastElement();
if (menuDoc) {
- menuDoc._forceActive = menuDoc._fitContentsToBox = menuDoc._isLinkButton = menuDoc._noShadow = menuDoc.noHighlighting = containerDoc._isInPlaceContainer;
- DocUtils.MakeLink({ doc: dv.rootDoc }, { doc: menuDoc }, 'back link to container');
+ menuDoc.hideDecorations = menuDoc._forceActive = menuDoc._fitContentsToBox = menuDoc._isLinkButton = menuDoc._noShadow = menuDoc.noHighlighting = containerDoc._isInPlaceContainer;
+ if (!dv.allLinks.find(link => link.anchor1 === menuDoc || link.anchor2 === menuDoc)) {
+ DocUtils.MakeLink({ doc: dv.rootDoc }, { doc: menuDoc }, 'back link to container');
+ }
DocListCast(menuDoc[Doc.LayoutFieldKey(menuDoc)]).forEach(menuItem => {
- menuItem._isLinkButton = true;
+ menuItem.followAllLinks = menuItem._isLinkButton = true;
menuItem._followLinkLocation = 'inPlace';
});
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index e24b116d0..8fe5ad63f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1157,7 +1157,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
// if (SelectionManager.Views().length !== 1 || SelectionManager.Views()[0].Document !== doc) {
// SelectionManager.DeselectAll();
// }
- if (this.props.Document.scrollHeight || this.props.Document.scrollTop !== undefined || this.props.Document.currentTimecode !== undefined) {
+ if (this.props.Document.scrollHeight || this.props.Document.scrollTop !== undefined || this.props.Document.currentTimecode !== undefined || doc.type === DocumentType.MARKER) {
this.props.focus(doc, options);
} else {
const xfToCollection = options?.docTransform ?? Transform.Identity();
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index 2fb8e3d4c..3e8867c50 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -206,7 +206,6 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
@computed
get editAudioFollow() {
//NOTE: confusingly, the classnames for the following relationship JSX elements are the same as the for the description elements for shared CSS
- console.log('AudioFollow:' + this.audioFollow);
return (
<div className="linkEditor-zoomFollow">
<div className="linkEditor-zoomFollow-label">Play Target Audio:</div>
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 7accd49a4..76d6d3532 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -166,7 +166,8 @@ export interface DocumentViewSharedProps {
// these props are specific to DocuentViews
export interface DocumentViewProps extends DocumentViewSharedProps {
// properties specific to DocumentViews but not to FieldView
- hideResizeHandles?: boolean; // whether to suppress DocumentDecorations when this document is selected
+ hideDecorations?: boolean; // whether to suppress all DocumentDecorations when doc is selected
+ hideResizeHandles?: boolean; // whether to suppress resized handles on doc decorations when this document is selected
hideTitle?: boolean; // forces suppression of title. e.g, treeView document labels suppress titles in case they are globally active via settings
hideDecorationTitle?: boolean; // forces suppression of title. e.g, treeView document labels suppress titles in case they are globally active via settings
hideDocumentButtonBar?: boolean;
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index d0df41023..d67481b22 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -14,7 +14,7 @@ import { TraceMobx } from '../../../fields/util';
import { emptyFunction, OmitKeys, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../Utils';
import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils';
import { CognitiveServices, Confidence, Service, Tag } from '../../cognitive_services/CognitiveServices';
-import { DocUtils } from '../../documents/Documents';
+import { Docs, DocUtils } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
import { Networking } from '../../Network';
import { DragManager } from '../../util/DragManager';
@@ -49,21 +49,58 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
return FieldView.LayoutString(ImageBox, fieldKey);
}
private _dropDisposer?: DragManager.DragDropDisposer;
+ private _transitioning: any; // timer for setting view spec properties
private _disposers: { [name: string]: IReactionDisposer } = {};
private _getAnchor: (savedAnnotations?: ObservableMap<number, HTMLDivElement[]>) => Opt<Doc> = () => undefined;
@observable _curSuffix = '';
@observable _uploadIcon = uploadIcons.idle;
+ @observable _focusViewScale: number | undefined = 1;
+ @observable _focusPanX: number | undefined = 0;
+ @observable _focusPanY: number | undefined = 0;
+ get viewScale() {
+ return this._focusViewScale || StrCast(this.layoutDoc._viewScale);
+ }
+ get panX() {
+ return this._focusPanX || StrCast(this.layoutDoc._panX);
+ }
+ get panY() {
+ return this._focusPanY || StrCast(this.layoutDoc._panY);
+ }
protected createDropTarget = (ele: HTMLDivElement) => {
this._dropDisposer?.();
ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.props.Document));
};
- setViewSpec = (anchor: Doc, preview: boolean) => {}; // sets viewing information for a componentview, typically when following a link. 'preview' tells the view to use the values without writing to the document
+
+ @action
+ setViewSpec = (anchor: Doc, preview: boolean) => {
+ if (preview && anchor._viewScale !== undefined) {
+ this._focusViewScale = Cast(anchor._viewScale, 'number', null);
+ this._focusPanX = Cast(anchor._panX, 'number', null);
+ this._focusPanY = Cast(anchor._panX, 'number', null);
+ } else if (anchor._viewScale !== undefined) {
+ const smoothTime = NumCast(anchor.viewTransitionTime);
+ this.layoutDoc.viewTransition = `all ${smoothTime}ms`;
+ this.layoutDoc._panX = NumCast(anchor._panX, NumCast(this.layoutDoc._panY));
+ this.layoutDoc._panY = NumCast(anchor._panY, NumCast(this.layoutDoc._panX));
+ this.layoutDoc._viewScale = NumCast(anchor._viewScale, NumCast(this.layoutDoc._viewScale));
+ if (anchor.type === DocumentType.MARKER) {
+ this.dataDoc[this.annotationKey] = new List<Doc>(DocListCast(anchor._annotations));
+ }
+ clearTimeout(this._transitioning);
+ this._transitioning = setTimeout(() => (this.layoutDoc.viewTransition = undefined), smoothTime);
+ }
+ }; // sets viewing information for a componentview, typically when following a link. 'preview' tells the view to use the values without writing to the document
getAnchor = () => {
- const anchor = this._getAnchor?.(this._savedAnnotations);
- anchor && this.addDocument(anchor);
- return anchor ?? this.rootDoc;
+ const zoomedAnchor = () => Docs.Create.ImageanchorDocument({ viewTransitionTime: 1000, _viewScale: NumCast(this.layoutDoc._viewScale), _panX: NumCast(this.layoutDoc._panX), _panY: NumCast(this.layoutDoc._panY) });
+ const anchor = this._getAnchor?.(this._savedAnnotations) ?? (this.layoutDoc.viewScale ? zoomedAnchor() : undefined);
+ if (anchor) {
+ anchor._annotations = new List<Doc>(DocListCast(this.dataDoc[this.annotationKey]));
+ this.addDocument(anchor);
+ return anchor;
+ }
+ return this.rootDoc;
};
componentDidMount() {
@@ -90,6 +127,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
}
componentWillUnmount() {
+ clearTimeout(this._transitioning);
Object.values(this._disposers).forEach(disposer => disposer?.());
}
@@ -283,9 +321,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
setTimeout(
action(() => {
this._uploadIcon = idle;
- if (data) {
- dataDoc[this.fieldKey] = data;
- }
+ data && (dataDoc[this.fieldKey] = data);
}),
2000
);
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index b495a9399..8d805c663 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -509,8 +509,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
static NavigateToTarget(targetDoc: Doc, activeItem: Doc, openInTab: any, srcContext: Doc, finished?: () => void) {
if ((activeItem.presPinLayout || activeItem.presPinView) && DocCast(targetDoc.context)?._currentFrame === undefined) {
const transTime = NumCast(activeItem.presTransition, 500);
- const presTransitionTime = `all ${transTime}ms`;
- targetDoc._dataTransition = presTransitionTime;
+ targetDoc._dataTransition = `all ${transTime}ms`;
targetDoc.x = NumCast(activeItem.presX, NumCast(targetDoc.x));
targetDoc.y = NumCast(activeItem.presY, NumCast(targetDoc.y));
targetDoc.rotation = NumCast(activeItem.presRot, NumCast(targetDoc.rotation));