aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/DocumentManager.ts5
-rw-r--r--src/client/util/SelectionManager.ts7
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx4
-rw-r--r--src/client/views/collections/TreeView.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.scss1
-rw-r--r--src/client/views/nodes/DocumentView.tsx40
6 files changed, 34 insertions, 25 deletions
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 01230bc06..3c59a8060 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -327,14 +327,15 @@ export class DocumentManager {
if (options.zoomTextSelections && Doc.UnhighlightTimer && contextView && viewSpec.text_html) {
// if the docView is a text anchor, the contextView is the PDF/Web/Text doc
- contextView.htmlOverlayEffect = StrCast(options?.effect?.presentation_effect, StrCast(options?.effect?.followLinkAnimEffect));
+ contextView.htmlOverlayEffect = options.effect;
+ contextView.textHtmlOverlayTime = options.zoomTime;
contextView.textHtmlOverlay = StrCast(targetDoc.text_html);
DocumentManager._overlayViews.add(contextView);
}
Doc.AddUnHighlightWatcher(() => {
docView.rootDoc[Animation] = undefined;
DocumentManager.removeOverlayViews();
- contextView && (contextView.htmlOverlayEffect = '');
+ contextView && (contextView.htmlOverlayEffect = undefined);
});
}
}
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index e864458d8..f7e6fa2dc 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -64,11 +64,8 @@ export namespace SelectionManager {
manager.SelectSchemaViewDoc(document);
}
- // computed functions, such as used in IsSelected generate errors if they're called outside of a
- // reaction context. Specifying the context with 'outsideReaction' allows an efficiency feature
- // to avoid unnecessary mobx invalidations when running inside a reaction.
- export function IsSelected(dv?: DocumentView | Doc): boolean {
- return (dv instanceof Doc ? Array.from(dv[DocViews]) : dv ? [dv] : []).some(dv => dv?.SELECTED);
+ export function IsSelected(doc?: Doc): boolean {
+ return Array.from(doc?.[DocViews] ?? []).some(dv => dv?.SELECTED);
}
export function DeselectAll(except?: Doc): void {
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 584098d35..3351ca48e 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -784,7 +784,7 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
// renders anchor LabelBox
renderInner = computedFn(function (this: StackedTimelineAnchor, mark: Doc, script: undefined | (() => ScriptField), doublescript: undefined | (() => ScriptField), screenXf: () => Transform, width: () => number, height: () => number) {
- const anchor = observable({ view: undefined as any });
+ const anchor = observable({ view: undefined as Opt<DocumentView> | null });
const focusFunc = (doc: Doc, options: DocFocusOptions): number | undefined => {
this.props.playLink(mark, options);
return undefined;
@@ -838,7 +838,7 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
return (
<div style={{ pointerEvents: this.noEvents ? 'none' : undefined }}>
{inner.view}
- {!inner.anchor.view || !SelectionManager.IsSelected(inner.anchor.view) ? null : (
+ {!inner.anchor.view || !inner.anchor.view.SELECTED ? null : (
<>
<div key="left" className="collectionStackedTimeline-left-resizer" style={{ pointerEvents: this.noEvents ? 'none' : undefined }} onPointerDown={e => this.onAnchorDown(e, this.props.mark, true)} />
<div key="right" className="collectionStackedTimeline-resizer" style={{ pointerEvents: this.noEvents ? 'none' : undefined }} onPointerDown={e => this.onAnchorDown(e, this.props.mark, false)} />
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index dbce45fda..004857ed1 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -165,7 +165,7 @@ export class TreeView extends React.Component<TreeViewProps> {
return this.childDocList(this.fieldKey + '_annotations');
}
@computed get selected() {
- return SelectionManager.IsSelected(this._docRef);
+ return this._docRef?.SELECTED;
}
childDocList(field: string) {
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index 505e937c5..406a1b8fb 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -61,7 +61,6 @@
.documentView-htmlOverlayInner {
box-shadow: black 0.2vw 0.2vw 0.8vw;
background: rgb(255, 255, 255);
- overflow: auto;
position: relative;
margin: auto;
padding: 20px;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 9d30a92b0..66a431bf0 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1364,9 +1364,10 @@ export class DocumentView extends React.Component<DocumentViewProps> {
}
@observable public docView: DocumentViewInternal | undefined | null;
@observable public textHtmlOverlay: Opt<string>;
+ @observable public textHtmlOverlayTime: Opt<number>;
@observable private _isHovering = false;
- public htmlOverlayEffect = '';
+ public htmlOverlayEffect: Opt<Doc>;
public get displayName() {
return 'DocumentView(' + this.props.Document?.title + ')';
} // this makes mobx trace() statements more descriptive
@@ -1596,7 +1597,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
scaleToScreenSpace = () => (1 / (this.props.NativeDimScaling?.() || 1)) * this.screenToLocalTransform().Scale;
docViewPathFunc = () => this.docViewPath;
- isSelected = () => SelectionManager.IsSelected(this);
+ isSelected = () => this.SELECTED;
select = (extendSelection: boolean, focusSelection?: boolean) => {
if (this.isSelected() && SelectionManager.Views().length > 1) SelectionManager.DeselectView(this);
else {
@@ -1643,19 +1644,30 @@ export class DocumentView extends React.Component<DocumentViewProps> {
Object.values(this._disposers).forEach(disposer => disposer?.());
!BoolCast(this.props.Document.dontRegisterView, this.props.dontRegisterView) && DocumentManager.Instance.RemoveView(this);
}
+ // want the htmloverlay to be able to fade in but we also want it to be display 'none' until it is needed.
+ // unfortunately, CSS can't transition animate any properties for something that is display 'none'.
+ // so we need to first activate the div, then, after a render timeout, start the opacity transition.
+ @observable enableHtmlOverlayTransitions: boolean = false;
@computed get htmlOverlay() {
- return !this.textHtmlOverlay ? null : (
- <div className="documentView-htmlOverlay">
- <div className="documentView-htmlOverlayInner">
- <Fade delay={0} duration={500}>
- {DocumentViewInternal.AnimationEffect(
- <div className="webBox-textHighlight">
- <ObserverJsxParser autoCloseVoidElements={true} key={42} onError={(e: any) => console.log('PARSE error', e)} renderInWrapper={false} jsx={StrCast(this.textHtmlOverlay)} />
- </div>,
- { presentation_effect: this.htmlOverlayEffect ?? 'Zoom' } as any as Doc,
- this.rootDoc
- )}{' '}
- </Fade>
+ const effect = StrCast(this.htmlOverlayEffect?.presentation_effect, StrCast(this.htmlOverlayEffect?.followLinkAnimEffect));
+ return (
+ <div
+ className="documentView-htmlOverlay"
+ ref={r => {
+ const val = r?.style.display !== 'none'; // if the outer overlay has been displayed, trigger the innner div to start it's opacity fade in transition
+ if (r && val !== this.enableHtmlOverlayTransitions) {
+ setTimeout(action(() => (this.enableHtmlOverlayTransitions = val)));
+ }
+ }}
+ style={{ display: !this.textHtmlOverlay ? 'none' : undefined }}>
+ <div className="documentView-htmlOverlayInner" style={{ transition: `all 500ms`, opacity: this.enableHtmlOverlayTransitions ? 0.9 : 0 }}>
+ {DocumentViewInternal.AnimationEffect(
+ <div className="webBox-textHighlight">
+ <ObserverJsxParser autoCloseVoidElements={true} key={42} onError={(e: any) => console.log('PARSE error', e)} renderInWrapper={false} jsx={StrCast(this.textHtmlOverlay)} />
+ </div>,
+ { ...(this.htmlOverlayEffect ?? {}), presentation_effect: effect ?? PresEffect.Zoom } as any as Doc,
+ this.rootDoc
+ )}
</div>
</div>
);