aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/pdf/Annotation.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2024-04-24 14:56:48 -0400
committerbobzel <zzzman@gmail.com>2024-04-24 14:56:48 -0400
commitaa4f7b37483c516b92181d3374d3151972b98383 (patch)
tree042520fc1fad30c00e27c532a872b4129f29264d /src/client/views/pdf/Annotation.tsx
parent9d69ab27de83ead3e499edc9028ba85749407a1e (diff)
fixed search on pdfs to display results when pDF is not selected. fixed presentation transitions to animate. changed so that annotaitons on pdfs would highlight when following a pres slide. fixed scrolling to annotations (and other viewSpecs) from presentations by using the slide target, not the slide as the focus document. cleaned up search and fixed to unhighlight searches on close. fixe pdf search unhighligting to work.
Diffstat (limited to 'src/client/views/pdf/Annotation.tsx')
-rw-r--r--src/client/views/pdf/Annotation.tsx89
1 files changed, 53 insertions, 36 deletions
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 053c88e17..38578837a 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -1,18 +1,20 @@
+/* eslint-disable react/jsx-props-no-spreading */
import { action, computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, DocListCast, Opt } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
-import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types';
+import { BoolCast, DocCast, NumCast, StrCast } from '../../../fields/Types';
import { LinkFollower } from '../../util/LinkFollower';
import { LinkManager } from '../../util/LinkManager';
-import { undoBatch } from '../../util/UndoManager';
+import { undoable } from '../../util/UndoManager';
+import { ObservableReactComponent } from '../ObservableReactComponent';
import { OpenWhere } from '../nodes/DocumentView';
import { FieldViewProps } from '../nodes/FieldView';
import { AnchorMenu } from './AnchorMenu';
import './Annotation.scss';
-import { ObservableReactComponent } from '../ObservableReactComponent';
+import { Highlight } from '../../../fields/DocSymbols';
interface IAnnotationProps extends FieldViewProps {
anno: Doc;
@@ -27,11 +29,41 @@ export class Annotation extends ObservableReactComponent<IAnnotationProps> {
super(props);
makeObservable(this);
}
+
+ @computed get linkHighlighted() {
+ const found = LinkManager.Instance.getAllDirectLinks(this._props.anno).find(link => {
+ const a1 = LinkManager.getOppositeAnchor(link, this._props.anno);
+ return a1 && Doc.GetBrushStatus(DocCast(a1.annotationOn, a1));
+ });
+ return found;
+ }
+ linkHighlightedFunc = () => this.linkHighlighted;
+ highlightedFunc = () => this._props.anno[Highlight];
+
+ deleteAnnotation = undoable(() => {
+ const docAnnotations = DocListCast(this._props.dataDoc[this._props.fieldKey]);
+ this._props.dataDoc[this._props.fieldKey] = new List<Doc>(docAnnotations.filter(a => a !== this._props.anno));
+ AnchorMenu.Instance.fadeOut(true);
+ this._props.select(false);
+ }, 'delete annotation');
+
+ pinToPres = undoable(() => this._props.pinToPres(this._props.anno, {}), 'pin to pres');
+
render() {
return (
<div style={{ display: this._props.anno.textCopied && !Doc.GetBrushHighlightStatus(this._props.anno) ? 'none' : undefined }}>
{DocListCast(this._props.anno.text_inlineAnnotations).map(a => (
- <RegionAnnotation pointerEvents={this._props.pointerEvents} {...this._props} document={a} key={a[Id]} />
+ // eslint-disable-next-line no-use-before-define
+ <RegionAnnotation
+ pointerEvents={this._props.pointerEvents}
+ {...this._props}
+ highlighted={this.highlightedFunc}
+ linkHighlighted={this.linkHighlightedFunc}
+ pinToPres={this.pinToPres}
+ deleteAnnotation={this.deleteAnnotation}
+ document={a}
+ key={a[Id]}
+ />
))}
</div>
);
@@ -40,49 +72,41 @@ export class Annotation extends ObservableReactComponent<IAnnotationProps> {
interface IRegionAnnotationProps extends IAnnotationProps {
document: Doc;
+ linkHighlighted: () => Doc | undefined;
+ highlighted: () => any;
+ deleteAnnotation: () => void;
+ pinToPres: (...args: any[]) => void;
pointerEvents?: () => Opt<string>;
}
@observer
class RegionAnnotation extends ObservableReactComponent<IRegionAnnotationProps> {
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
- @computed get annoTextRegion() {
- return Cast(this._props.document.annoTextRegion, Doc, null) || this._props.document;
+ @computed get regionDoc() {
+ return DocCast(this._props.document.embedContainer, this._props.document);
}
- @undoBatch
- deleteAnnotation = () => {
- const docAnnotations = DocListCast(this._props.dataDoc[this._props.fieldKey]);
- this._props.dataDoc[this._props.fieldKey] = new List<Doc>(docAnnotations.filter(a => a !== this.annoTextRegion));
- AnchorMenu.Instance.fadeOut(true);
- this._props.select(false);
- };
-
- @undoBatch
- pinToPres = () => this._props.pinToPres(this.annoTextRegion, {});
+ makeTargetToggle = undoable(() => { this.regionDoc.followLinkToggle = !this.regionDoc.followLinkToggle }, "set link toggle"); // prettier-ignore
- @undoBatch
- makeTargetToggle = () => { this.annoTextRegion.followLinkToggle = !this.annoTextRegion.followLinkToggle }; // prettier-ignore
+ isTargetToggler = () => BoolCast(this.regionDoc.followLinkToggle);
- isTargetToggler = () => BoolCast(this.annoTextRegion.followLinkToggle);
- @undoBatch
- showTargetTrail = (anchor: Doc) => {
+ showTargetTrail = undoable((anchor: Doc) => {
const trail = DocCast(anchor.presentationTrail);
if (trail) {
Doc.ActivePresentation = trail;
this._props.addDocTab(trail, OpenWhere.replaceRight);
}
- };
+ }, 'show target trail');
@action
onContextMenu = (e: React.MouseEvent) => {
AnchorMenu.Instance.Status = 'annotation';
- AnchorMenu.Instance.Delete = this.deleteAnnotation.bind(this);
+ AnchorMenu.Instance.Delete = this._props.deleteAnnotation;
AnchorMenu.Instance.Pinned = false;
- AnchorMenu.Instance.PinToPres = this.pinToPres;
+ AnchorMenu.Instance.PinToPres = this._props.pinToPres;
AnchorMenu.Instance.MakeTargetToggle = this.makeTargetToggle;
AnchorMenu.Instance.IsTargetToggler = this.isTargetToggler;
- AnchorMenu.Instance.ShowTargetTrail = () => this.showTargetTrail(this.annoTextRegion);
+ AnchorMenu.Instance.ShowTargetTrail = () => this.showTargetTrail(this.regionDoc);
AnchorMenu.Instance.jumpTo(e.clientX, e.clientY, true);
e.stopPropagation();
e.preventDefault();
@@ -94,19 +118,12 @@ class RegionAnnotation extends ObservableReactComponent<IRegionAnnotationProps>
e.preventDefault();
} else if (e.button === 0) {
e.stopPropagation();
- LinkFollower.FollowLink(undefined, this.annoTextRegion, false);
+ LinkFollower.FollowLink(undefined, this.regionDoc, false);
}
};
- @computed get linkHighlighted() {
- for (const link of LinkManager.Instance.getAllDirectLinks(this._props.document)) {
- const a1 = LinkManager.getOppositeAnchor(link, this._props.document);
- if (a1 && Doc.GetBrushStatus(DocCast(a1.annotationOn, this._props.document))) return true;
- }
- }
-
render() {
- const brushed = this.annoTextRegion && Doc.GetBrushHighlightStatus(this.annoTextRegion);
+ const brushed = this.regionDoc && Doc.GetBrushHighlightStatus(this.regionDoc);
return (
<div
className="htmlAnnotation"
@@ -128,8 +145,8 @@ class RegionAnnotation extends ObservableReactComponent<IRegionAnnotationProps>
height: NumCast(this._props.document._height),
opacity: brushed === Doc.DocBrushStatus.highlighted ? 0.5 : undefined,
pointerEvents: this._props.pointerEvents?.() as any,
- outline: brushed === Doc.DocBrushStatus.unbrushed && this.linkHighlighted ? 'solid 1px lightBlue' : undefined,
- backgroundColor: brushed === Doc.DocBrushStatus.highlighted ? 'orange' : StrCast(this._props.document.backgroundColor),
+ outline: this._props.linkHighlighted() ? 'solid 1px lightBlue' : undefined,
+ backgroundColor: this._props.highlighted() ? 'orange' : StrCast(this._props.document.backgroundColor),
}}
/>
);