diff options
-rw-r--r-- | src/client/views/DocumentButtonBar.tsx | 22 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 11 | ||||
-rw-r--r-- | src/client/views/linking/LinkEditor.tsx | 14 | ||||
-rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 11 | ||||
-rw-r--r-- | src/client/views/nodes/trails/PresBox.tsx | 72 |
5 files changed, 80 insertions, 50 deletions
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 681349ccf..ecf330792 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -386,18 +386,18 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV style={{ backgroundColor: this._isRecording ? Colors.ERROR_RED : Colors.DARK_GRAY, color: Colors.WHITE }} onPointerDown={action((e: React.PointerEvent) => { this._isRecording = true; - this.props.views().map( - view => - view && - DocumentViewInternal.recordAudioAnnotation( - view.dataDoc, - view.LayoutFieldKey, - stopFunc => (this._stopFunc = stopFunc), - action(() => (this._isRecording = false)) - ) - ); + this.props.views().map(view => view && DocumentViewInternal.recordAudioAnnotation(view.dataDoc, view.LayoutFieldKey, stopFunc => (this._stopFunc = stopFunc), emptyFunction)); const b = UndoManager.StartBatch('Recording'); - setupMoveUpEvents(this, e, returnFalse, () => this._stopFunc(), emptyFunction); + setupMoveUpEvents( + this, + e, + returnFalse, + action(() => { + this._isRecording = false; + this._stopFunc(); + }), + emptyFunction + ); })}> <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="microphone" /> </div> diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 8a97797c7..57cccec4a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1532,17 +1532,18 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection @action scrollFocus = (anchor: Doc, smooth: boolean) => { - let focusSpeed: Opt<number>; - PresBox.restoreTargetDocView( + const focusSpeed = !smooth ? 0 : NumCast(anchor.presTransition); + return PresBox.restoreTargetDocView( this.rootDoc, // { pinDocLayout: BoolCast(anchor.presPinDocLayout) }, anchor, - (focusSpeed = !smooth ? 0 : NumCast(anchor.presTransition)), + focusSpeed, { pannable: anchor.presPinData ? true : false, } - ); - return focusSpeed; + ) + ? focusSpeed + : undefined; }; // 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 = () => { diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index d90a91ab7..8c4d756d2 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -297,13 +297,13 @@ export class LinkEditor extends React.Component<LinkEditorProps> { ); } - @computed get sourceAnchor() { + @computed get destinationAnchor() { const ldoc = this.props.linkDoc; if (this.props.sourceDoc !== ldoc.anchor1 && this.props.sourceDoc !== ldoc.anchor2) { - if (Doc.AreProtosEqual(DocCast(DocCast(ldoc.anchor1).annotationOn), this.props.sourceDoc)) return DocCast(ldoc.anchor1); - if (Doc.AreProtosEqual(DocCast(DocCast(ldoc.anchor2).annotationOn), this.props.sourceDoc)) return DocCast(ldoc.anchor2); + if (Doc.AreProtosEqual(DocCast(DocCast(ldoc.anchor1).annotationOn), this.props.sourceDoc)) return DocCast(ldoc.anchor2); + if (Doc.AreProtosEqual(DocCast(DocCast(ldoc.anchor2).annotationOn), this.props.sourceDoc)) return DocCast(ldoc.anchor1); } - return this.props.sourceDoc; + return LinkManager.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc) ?? this.props.sourceDoc; } @action changeEffectDropdown = () => { @@ -313,7 +313,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> { @undoBatch changeEffect = action((follow: string) => { this.openEffectDropdown = false; - this.sourceAnchor.presEffect = follow; + this.destinationAnchor.presEffect = follow; }); @computed @@ -323,7 +323,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> { <div className="linkEditor-followingDropdown-label">Transition Effect:</div> <div className="linkEditor-followingDropdown-dropdown"> <div className="linkEditor-followingDropdown-header" onPointerDown={this.changeEffectDropdown}> - {StrCast(this.sourceAnchor.presEffect, 'default')} + {StrCast(this.destinationAnchor.presEffect, 'default')} <FontAwesomeIcon className="linkEditor-followingDropdown-icon" icon={this.openEffectDropdown ? 'chevron-up' : 'chevron-down'} size={'lg'} /> </div> <div className="linkEditor-followingDropdown-optionsList" style={{ display: this.openEffectDropdown ? '' : 'none' }}> @@ -447,7 +447,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> { </div> {this.followingDropdown} {this.effectDropdown} - {PresBox.inputter('0.1', '0.1', '10', NumCast(this.sourceAnchor.presTransition) / 1000, true, (val: string) => PresBox.SetTransitionTime(val, (timeInMS: number) => (this.sourceAnchor.presTransition = timeInMS)))} + {PresBox.inputter('0.1', '0.1', '10', NumCast(this.destinationAnchor.presTransition) / 1000, true, (val: string) => PresBox.SetTransitionTime(val, (timeInMS: number) => (this.destinationAnchor.presTransition = timeInMS)))} <div className={'slider-headers'} style={{ diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 4092a2575..1d79febdf 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -63,12 +63,12 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp @action scrollFocus = (anchor: Doc, smooth: boolean) => { - let focusSpeed: Opt<number>; - PresBox.restoreTargetDocView( + const focusSpeed = !smooth ? 0 : NumCast(anchor.presTransition); + return PresBox.restoreTargetDocView( this.rootDoc, // { pinDocLayout: BoolCast(anchor.presPinDocLayout) }, anchor, - (focusSpeed = !smooth ? 0 : NumCast(anchor.presTransition)), + focusSpeed, !anchor.presPinData ? {} : { @@ -76,8 +76,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp dataannos: anchor.presAnnotations !== undefined, dataview: true, } - ); - return focusSpeed; + ) + ? focusSpeed + : undefined; }; // 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 = () => { diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 7235481e0..e19b53f50 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -365,25 +365,46 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @action static restoreTargetDocView(bestTarget: Doc, pinProps: PinProps | undefined, activeItem: Doc, transTime: number, pinDataTypes = this.pinDataTypes(bestTarget)) { const presTransitionTime = `all ${transTime}ms`; - bestTarget._viewTransition = presTransitionTime; + let changed = false; if (pinProps?.pinDocLayout) { - const transTime = NumCast(activeItem.presTransition, 500); - bestTarget._dataTransition = `all ${transTime}ms`; - bestTarget.x = NumCast(activeItem.presX, NumCast(bestTarget.x)); - bestTarget.y = NumCast(activeItem.presY, NumCast(bestTarget.y)); - bestTarget.rotation = NumCast(activeItem.presRot, NumCast(bestTarget.rotation)); - bestTarget.width = NumCast(activeItem.presWidth, NumCast(bestTarget.width)); - bestTarget.height = NumCast(activeItem.presHeight, NumCast(bestTarget.height)); - setTimeout(() => (bestTarget._dataTransition = undefined), transTime + 10); + if ( + bestTarget.x !== NumCast(activeItem.presX, NumCast(bestTarget.x)) || + bestTarget.y !== NumCast(activeItem.presY, NumCast(bestTarget.y)) || + bestTarget.rotation !== NumCast(activeItem.presRot, NumCast(bestTarget.rotation)) || + bestTarget.width !== NumCast(activeItem.presWidth, NumCast(bestTarget.width)) || + bestTarget.height !== NumCast(activeItem.presHeight, NumCast(bestTarget.height)) + ) { + bestTarget._dataTransition = `all ${transTime}ms`; + bestTarget.x = NumCast(activeItem.presX, NumCast(bestTarget.x)); + bestTarget.y = NumCast(activeItem.presY, NumCast(bestTarget.y)); + bestTarget.rotation = NumCast(activeItem.presRot, NumCast(bestTarget.rotation)); + bestTarget.width = NumCast(activeItem.presWidth, NumCast(bestTarget.width)); + bestTarget.height = NumCast(activeItem.presHeight, NumCast(bestTarget.height)); + setTimeout(() => (bestTarget._dataTransition = undefined), transTime + 10); + changed = true; + } + } + if (pinDataTypes.clippable) { + if (bestTarget._clipWidth !== activeItem.presPinClipWidth) { + bestTarget._clipWidth = activeItem.presPinClipWidth; + changed = true; + } + } + if (pinDataTypes.temporal) { + if (bestTarget._currentTimecode !== activeItem.presStartTime) { + bestTarget._currentTimecode = activeItem.presStartTime; + changed = true; + } } - if (pinDataTypes.clippable) bestTarget._clipWidth = activeItem.presPinClipWidth; - if (pinDataTypes.temporal) bestTarget._currentTimecode = activeItem.presStartTime; if (pinDataTypes.scrollable) { - bestTarget._scrollTop = activeItem.presPinViewScroll; - const contentBounds = Cast(activeItem.presPinViewBounds, listSpec('number')); - if (contentBounds) { - const dv = DocumentManager.Instance.getDocumentView(bestTarget)?.ComponentView; - dv?.brushView?.({ panX: (contentBounds[0] + contentBounds[2]) / 2, panY: (contentBounds[1] + contentBounds[3]) / 2, width: contentBounds[2] - contentBounds[0], height: contentBounds[3] - contentBounds[1] }); + if (bestTarget._scrollTop !== activeItem.presPinViewScroll) { + bestTarget._scrollTop = activeItem.presPinViewScroll; + changed = true; + const contentBounds = Cast(activeItem.presPinViewBounds, listSpec('number')); + if (contentBounds) { + const dv = DocumentManager.Instance.getDocumentView(bestTarget)?.ComponentView; + dv?.brushView?.({ panX: (contentBounds[0] + contentBounds[2]) / 2, panY: (contentBounds[1] + contentBounds[3]) / 2, width: contentBounds[2] - contentBounds[0], height: contentBounds[3] - contentBounds[1] }); + } } } if (pinDataTypes.dataannos) { @@ -397,6 +418,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } if (pinDataTypes.textview && activeItem.presData !== undefined) Doc.GetProto(bestTarget)[Doc.LayoutFieldKey(bestTarget)] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData; if (pinDataTypes.poslayoutview) { + changed = true; StrListCast(activeItem.presPinLayoutData) .map(str => JSON.parse(str) as { id: string; x: number; y: number; w: number; h: number }) .forEach(data => { @@ -428,12 +450,18 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { dv.ComponentView?.brushView?.(viewport); } } else { - bestTarget._panX = activeItem.presPinViewX; - bestTarget._panY = activeItem.presPinViewY; - bestTarget._viewScale = activeItem.presPinViewScale; + if (bestTarget._panX !== activeItem.presPinViewX || bestTarget._panY !== activeItem.presPinViewY || bestTarget._viewScale !== activeItem.presPinViewScale) { + bestTarget._panX = activeItem.presPinViewX; + bestTarget._panY = activeItem.presPinViewY; + bestTarget._viewScale = activeItem.presPinViewScale; + changed = true; + } } } - return setTimeout(() => (bestTarget._viewTransition = undefined), transTime + 10); + if (changed) { + bestTarget._viewTransition = presTransitionTime; + return setTimeout(() => (bestTarget._viewTransition = undefined), transTime + 10); + } } /// copies values from the targetDoc (which is the prototype of the pinDoc) to @@ -495,7 +523,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { } } - static _navTimer: NodeJS.Timeout; + static _navTimer: NodeJS.Timeout | undefined; /** * This method makes sure that cursor navigates to the element that * has the option open and last in the group. @@ -563,7 +591,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { // adjust the pan and scale to that of the pinView when it was added. const pinDocLayout = (BoolCast(activeItem.presPinLayout) || BoolCast(activeItem.presPinView)) && DocCast(targetDoc.context)?._currentFrame === undefined; if (activeItem.presPinData || activeItem.presPinView || pinDocLayout) { - clearTimeout(PresBox._navTimer); + PresBox._navTimer && clearTimeout(PresBox._navTimer); // targetDoc may or may not be displayed. this gets the first available document (or alias) view that matches targetDoc const bestTargetView = DocumentManager.Instance.getFirstDocumentView(targetDoc); if (bestTargetView?.props.Document) PresBox._navTimer = PresBox.restoreTargetDocView(bestTargetView?.props.Document, { pinDocLayout }, activeItem, NumCast(activeItem.presTransition, 500)); |