aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/pdf
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/pdf')
-rw-r--r--src/client/views/pdf/AnchorMenu.tsx39
-rw-r--r--src/client/views/pdf/Annotation.tsx86
-rw-r--r--src/client/views/pdf/GPTPopup/GPTPopup.tsx74
-rw-r--r--src/client/views/pdf/PDFViewer.scss1
-rw-r--r--src/client/views/pdf/PDFViewer.tsx252
5 files changed, 236 insertions, 216 deletions
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index 18cf633f4..d0688c338 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -1,12 +1,12 @@
-import React = require('react');
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { ColorPicker, Group, IconButton, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components';
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction } from 'mobx';
+import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
-import { ColorState } from 'react-color';
+import * as React from 'react';
+import { ColorResult } from 'react-color';
+import { Utils, returnFalse, setupMoveUpEvents, unimplementedFunction } from '../../../Utils';
import { Doc, Opt } from '../../../fields/Doc';
-import { returnFalse, setupMoveUpEvents, unimplementedFunction, Utils } from '../../../Utils';
-import { gptAPICall, GPTCallType } from '../../apis/gpt/GPT';
+import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT';
import { DocumentType } from '../../documents/DocumentTypes';
import { SelectionManager } from '../../util/SelectionManager';
import { SettingsManager } from '../../util/SettingsManager';
@@ -23,6 +23,13 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
private _commentRef = React.createRef<HTMLDivElement>();
private _cropRef = React.createRef<HTMLDivElement>();
+ constructor(props: any) {
+ super(props);
+ makeObservable(this);
+ AnchorMenu.Instance = this;
+ AnchorMenu.Instance._canFade = false;
+ }
+
@observable private highlightColor: string = 'rgba(245, 230, 95, 0.616)';
@observable public Status: 'marquee' | 'annotation' | '' = '';
@@ -50,21 +57,14 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
return this._left > 0;
}
- constructor(props: Readonly<{}>) {
- super(props);
-
- AnchorMenu.Instance = this;
- AnchorMenu.Instance._canFade = false;
- }
-
componentWillUnmount() {
this._disposer?.();
}
componentDidMount() {
this._disposer = reaction(
- () => SelectionManager.Views().slice(),
- selected => AnchorMenu.Instance.fadeOut(true)
+ () => SelectionManager.Views.slice(),
+ sel => AnchorMenu.Instance.fadeOut(true)
);
}
@@ -139,13 +139,10 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
}
@action changeHighlightColor = (color: string) => {
- const col: ColorState = {
+ const col: ColorResult = {
hex: color,
- hsl: { a: 0, h: 0, s: 0, l: 0, source: '' },
- hsv: { a: 0, h: 0, s: 0, v: 0, source: '' },
- rgb: { a: 0, r: 0, b: 0, g: 0, source: '' },
- oldHue: 0,
- source: '',
+ hsl: { a: 0, h: 0, s: 0, l: 0 },
+ rgb: { a: 0, r: 0, b: 0, g: 0 },
};
this.highlightColor = Utils.colorString(col);
};
@@ -155,7 +152,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
* all selected text available to summarize but its only supported for pdf and web ATM.
* @returns Whether the GPT icon for summarization should appear
*/
- canSummarize = () => SelectionManager.Docs().some(doc => [DocumentType.PDF, DocumentType.WEB].includes(doc.type as any));
+ canSummarize = () => SelectionManager.Docs.some(doc => [DocumentType.PDF, DocumentType.WEB].includes(doc.type as any));
render() {
const buttons =
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 52904b852..a1f5ce703 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -1,32 +1,37 @@
-import React = require('react');
-import { action, computed } from 'mobx';
+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 { LinkFollower } from '../../util/LinkFollower';
+import { LinkManager } from '../../util/LinkManager';
import { undoBatch } from '../../util/UndoManager';
import { OpenWhere } from '../nodes/DocumentView';
import { FieldViewProps } from '../nodes/FieldView';
import { AnchorMenu } from './AnchorMenu';
import './Annotation.scss';
-import { LinkManager } from '../../util/LinkManager';
+import { ObservableReactComponent } from '../ObservableReactComponent';
interface IAnnotationProps extends FieldViewProps {
anno: Doc;
dataDoc: Doc;
fieldKey: string;
- showInfo: (anno: Opt<Doc>) => void;
+ showInfo?: (anno: Opt<Doc>) => void;
pointerEvents?: () => Opt<string>;
}
@observer
-export class Annotation extends React.Component<IAnnotationProps> {
+export class Annotation extends ObservableReactComponent<IAnnotationProps> {
+ constructor(props: any) {
+ super(props);
+ makeObservable(this);
+ }
render() {
return (
- <div style={{ display: this.props.anno.textCopied && !Doc.isBrushedHighlightedDegree(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]} />
+ <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]} />
))}
</div>
);
@@ -38,23 +43,23 @@ interface IRegionAnnotationProps extends IAnnotationProps {
pointerEvents?: () => Opt<string>;
}
@observer
-class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
+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;
+ return Cast(this._props.document.annoTextRegion, Doc, null) || 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));
+ 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);
+ this._props.select(false);
};
@undoBatch
- pinToPres = () => this.props.pinToPres(this.annoTextRegion, {});
+ pinToPres = () => this._props.pinToPres(this.annoTextRegion, {});
@undoBatch
makeTargretToggle = () => (this.annoTextRegion.followLinkToggle = !this.annoTextRegion.followLinkToggle);
@@ -65,22 +70,28 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
const trail = DocCast(anchor.presentationTrail);
if (trail) {
Doc.ActivePresentation = trail;
- this.props.addDocTab(trail, OpenWhere.replaceRight);
+ this._props.addDocTab(trail, OpenWhere.replaceRight);
}
};
@action
+ onContextMenu = (e: React.MouseEvent) => {
+ AnchorMenu.Instance.Status = 'annotation';
+ AnchorMenu.Instance.Delete = this.deleteAnnotation.bind(this);
+ AnchorMenu.Instance.Pinned = false;
+ AnchorMenu.Instance.PinToPres = this.pinToPres;
+ AnchorMenu.Instance.MakeTargetToggle = this.makeTargretToggle;
+ AnchorMenu.Instance.IsTargetToggler = this.isTargetToggler;
+ AnchorMenu.Instance.ShowTargetTrail = () => this.showTargetTrail(this.annoTextRegion);
+ AnchorMenu.Instance.jumpTo(e.clientX, e.clientY, true);
+ e.stopPropagation();
+ e.preventDefault();
+ };
+ @action
onPointerDown = (e: React.PointerEvent) => {
if (e.button === 2 || e.ctrlKey) {
- AnchorMenu.Instance.Status = 'annotation';
- AnchorMenu.Instance.Delete = this.deleteAnnotation.bind(this);
- AnchorMenu.Instance.Pinned = false;
- AnchorMenu.Instance.PinToPres = this.pinToPres;
- AnchorMenu.Instance.MakeTargetToggle = this.makeTargretToggle;
- AnchorMenu.Instance.IsTargetToggler = this.isTargetToggler;
- AnchorMenu.Instance.ShowTargetTrail = () => this.showTargetTrail(this.annoTextRegion);
- AnchorMenu.Instance.jumpTo(e.clientX, e.clientY, true);
e.stopPropagation();
+ e.preventDefault();
} else if (e.button === 0) {
e.stopPropagation();
LinkFollower.FollowLink(undefined, this.annoTextRegion, false);
@@ -88,36 +99,37 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
};
@computed get linkHighlighted() {
- for (const link of LinkManager.Instance.getAllDirectLinks(this.props.document)) {
- const a1 = LinkManager.getOppositeAnchor(link, this.props.document);
- if (a1 && Doc.IsBrushedDegreeUnmemoized(DocCast(a1.annotationOn, this.props.document))) return true;
+ 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.isBrushedHighlightedDegree(this.annoTextRegion);
+ const brushed = this.annoTextRegion && Doc.GetBrushHighlightStatus(this.annoTextRegion);
return (
<div
className="htmlAnnotation"
ref={this._mainCont}
onPointerEnter={action(() => {
- Doc.BrushDoc(this.props.anno);
- this.props.showInfo(this.props.anno);
+ Doc.BrushDoc(this._props.anno);
+ this._props.showInfo?.(this._props.anno);
})}
onPointerLeave={action(() => {
- Doc.UnBrushDoc(this.props.anno);
- this.props.showInfo(undefined);
+ Doc.UnBrushDoc(this._props.anno);
+ this._props.showInfo?.(undefined);
})}
onPointerDown={this.onPointerDown}
+ onContextMenu={this.onContextMenu}
style={{
- left: NumCast(this.props.document.x),
- top: NumCast(this.props.document.y),
- width: NumCast(this.props.document._width),
- height: NumCast(this.props.document._height),
+ left: NumCast(this._props.document.x),
+ top: NumCast(this._props.document.y),
+ width: NumCast(this._props.document._width),
+ height: NumCast(this._props.document._height),
opacity: brushed === Doc.DocBrushStatus.highlighted ? 0.5 : undefined,
- pointerEvents: this.props.pointerEvents?.() as any,
+ 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),
+ backgroundColor: brushed === Doc.DocBrushStatus.highlighted ? 'orange' : StrCast(this._props.document.backgroundColor),
}}
/>
);
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
index 9b754588a..42562986f 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
@@ -1,19 +1,20 @@
-import React = require('react');
-import './GPTPopup.scss';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, observable } from 'mobx';
+import { Button, IconButton, Type } from 'browndash-components';
+import { action, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
+import * as React from 'react';
+import { CgClose } from 'react-icons/cg';
import ReactLoading from 'react-loading';
-import Typist from 'react-typist';
+import { TypeAnimation } from 'react-type-animation';
+import { Utils } from '../../../../Utils';
import { Doc } from '../../../../fields/Doc';
-import { DocUtils, Docs } from '../../../documents/Documents';
-import { Button, IconButton, Type } from 'browndash-components';
import { NumCast, StrCast } from '../../../../fields/Types';
-import { CgClose } from 'react-icons/cg';
-import { AnchorMenu } from '../AnchorMenu';
-import { gptImageCall } from '../../../apis/gpt/GPT';
import { Networking } from '../../../Network';
-import { Utils } from '../../../../Utils';
+import { gptImageCall } from '../../../apis/gpt/GPT';
+import { DocUtils, Docs } from '../../../documents/Documents';
+import { ObservableReactComponent } from '../../ObservableReactComponent';
+import { AnchorMenu } from '../AnchorMenu';
+import './GPTPopup.scss';
export enum GPTPopupMode {
SUMMARY,
@@ -24,7 +25,7 @@ export enum GPTPopupMode {
interface GPTPopupProps {}
@observer
-export class GPTPopup extends React.Component<GPTPopupProps> {
+export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
static Instance: GPTPopup;
@observable
@@ -128,7 +129,7 @@ export class GPTPopup extends React.Component<GPTPopupProps> {
} catch (err) {
console.log(err);
}
- GPTPopup.Instance.setLoading(false);
+ this.setLoading(false);
};
/**
@@ -179,6 +180,7 @@ export class GPTPopup extends React.Component<GPTPopupProps> {
constructor(props: GPTPopupProps) {
super(props);
+ makeObservable(this);
GPTPopup.Instance = this;
}
@@ -213,6 +215,31 @@ export class GPTPopup extends React.Component<GPTPopupProps> {
);
};
+ data = () => {
+ return (
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
+ {this.heading('GENERATED IMAGE')}
+ <div className="image-content-wrapper">
+ {this.imgUrls.map(rawSrc => (
+ <div className="img-wrapper">
+ <div className="img-container">
+ <img key={rawSrc[0]} src={rawSrc[0]} width={150} height={150} alt="dalle generation" />
+ </div>
+ <div className="btn-container">
+ <Button text="Save Image" onClick={() => this.transferToImage(rawSrc[1])} color={StrCast(Doc.UserDoc().userColor)} type={Type.TERT} />
+ </div>
+ </div>
+ ))}
+ </div>
+ {!this.loading && (
+ <>
+ <IconButton tooltip="Generate Again" onClick={this.generateImage} icon={<FontAwesomeIcon icon="redo-alt" size="lg" />} color={StrCast(Doc.UserDoc().userVariantColor)} />
+ </>
+ )}
+ </div>
+ );
+ };
+
summaryBox = () => (
<>
<div>
@@ -220,17 +247,18 @@ export class GPTPopup extends React.Component<GPTPopupProps> {
<div className="content-wrapper">
{!this.loading &&
(!this.done ? (
- <Typist
- key={this.text}
- avgTypingDelay={15}
- cursor={{ hideWhenDone: true }}
- onTypingDone={() => {
- setTimeout(() => {
- this.setDone(true);
- }, 500);
- }}>
- {this.text}
- </Typist>
+ <TypeAnimation
+ speed={50}
+ sequence={[
+ this.text,
+ () => {
+ setTimeout(() => {
+ this.setDone(true);
+ }, 500);
+ },
+ ]}
+ //cursor={{ hideWhenDone: true }}
+ />
) : (
this.text
))}
diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss
index cfe07f6cb..d3dd9f727 100644
--- a/src/client/views/pdf/PDFViewer.scss
+++ b/src/client/views/pdf/PDFViewer.scss
@@ -52,6 +52,7 @@
.textLayer {
pointer-events: all;
user-select: text;
+ z-index: 0;
}
}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 939928c1c..0d4cfda88 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -1,43 +1,40 @@
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as Pdfjs from 'pdfjs-dist';
import 'pdfjs-dist/web/pdf_viewer.css';
-import { Doc, DocListCast, Field, Opt } from '../../../fields/Doc';
+import * as PDFJSViewer from 'pdfjs-dist/web/pdf_viewer.mjs';
+import * as React from 'react';
+import { Doc, DocListCast, Opt } from '../../../fields/Doc';
import { Height } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { Cast, NumCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, returnAll, returnFalse, returnNone, returnTrue, returnZero, smoothScroll, Utils } from '../../../Utils';
+import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, returnAll, returnFalse, returnNone, returnZero, smoothScroll, Utils } from '../../../Utils';
import { DocUtils } from '../../documents/Documents';
-import { DragManager } from '../../util/DragManager';
import { SelectionManager } from '../../util/SelectionManager';
-import { SharingManager } from '../../util/SharingManager';
import { SnappingManager } from '../../util/SnappingManager';
import { MarqueeOptionsMenu } from '../collections/collectionFreeForm';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import { MarqueeAnnotator } from '../MarqueeAnnotator';
-import { DocFocusOptions, DocumentViewProps } from '../nodes/DocumentView';
-import { FieldViewProps } from '../nodes/FieldView';
-import { LinkDocPreview } from '../nodes/LinkDocPreview';
+import { FocusViewOptions, FieldViewProps } from '../nodes/FieldView';
+import { LinkInfo } from '../nodes/LinkDocPreview';
+import { PDFBox } from '../nodes/PDFBox';
+import { ObservableReactComponent } from '../ObservableReactComponent';
import { StyleProp } from '../StyleProvider';
import { AnchorMenu } from './AnchorMenu';
import { Annotation } from './Annotation';
-import './PDFViewer.scss';
-import React = require('react');
import { GPTPopup } from './GPTPopup/GPTPopup';
-import { InkingStroke } from '../InkingStroke';
-const PDFJSViewer = require('pdfjs-dist/web/pdf_viewer');
-const pdfjsLib = require('pdfjs-dist');
+import './PDFViewer.scss';
const _global = (window /* browser */ || global) /* node */ as any;
//pdfjsLib.GlobalWorkerOptions.workerSrc = `/assets/pdf.worker.js`;
// The workerSrc property shall be specified.
-pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@2.16.105/build/pdf.worker.js';
+Pdfjs.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@4.0.379/build/pdf.worker.mjs';
interface IViewerProps extends FieldViewProps {
+ pdfBox: PDFBox;
Document: Doc;
- rootDoc: Doc;
dataDoc: Doc;
layoutDoc: Doc;
fieldKey: string;
@@ -54,21 +51,25 @@ interface IViewerProps extends FieldViewProps {
* Handles rendering and virtualization of the pdf
*/
@observer
-export class PDFViewer extends React.Component<IViewerProps> {
+export class PDFViewer extends ObservableReactComponent<IViewerProps> {
static _annotationStyle: any = addStyleSheet();
- @observable private _pageSizes: { width: number; height: number }[] = [];
- @observable private _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
- @observable private _marqueeing: number[] | undefined;
- @observable private _textSelecting = true;
- @observable private _showWaiting = true;
- @observable private _overlayAnnoInfo: Opt<Doc>;
- @observable private Index: number = -1;
+
+ constructor(props: IViewerProps) {
+ super(props);
+ makeObservable(this);
+ }
+
+ @observable _pageSizes: { width: number; height: number }[] = [];
+ @observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
+ @observable _textSelecting = true;
+ @observable _showWaiting = true;
+ @observable Index: number = -1;
private _pdfViewer: any;
private _styleRule: any; // stylesheet rule for making hyperlinks clickable
private _retries = 0; // number of times tried to create the PDF viewer
private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void);
- private _setBrushViewer: undefined | ((view: { width: number; height: number; panX: number; panY: number }, transTime: number) => void);
+ private _marqueeref = React.createRef<MarqueeAnnotator>();
private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
private _disposers: { [name: string]: IReactionDisposer } = {};
private _viewer: React.RefObject<HTMLDivElement> = React.createRef();
@@ -90,44 +91,38 @@ export class PDFViewer extends React.Component<IViewerProps> {
@observable isAnnotating = false;
// key where data is stored
@computed get allAnnotations() {
- return DocUtils.FilterDocs(DocListCast(this.props.dataDoc[this.props.fieldKey + '_annotations']), this.props.childFilters(), this.props.childFiltersByRanges());
+ return DocUtils.FilterDocs(DocListCast(this._props.dataDoc[this._props.fieldKey + '_annotations']), this._props.childFilters(), this._props.childFiltersByRanges());
}
@computed get inlineTextAnnotations() {
return this.allAnnotations.filter(a => a.text_inlineAnnotations);
}
- componentDidMount = async () => {
+ componentDidMount() {
runInAction(() => (this._showWaiting = true));
this.setupPdfJsViewer();
this._mainCont.current?.addEventListener('scroll', e => ((e.target as any).scrollLeft = 0));
this._disposers.layout_autoHeight = reaction(
- () => this.props.layoutDoc._layout_autoHeight,
+ () => this._props.layoutDoc._layout_autoHeight,
layout_autoHeight => {
if (layout_autoHeight) {
- this.props.layoutDoc._nativeHeight = NumCast(this.props.Document[this.props.fieldKey + '_nativeHeight']);
- this.props.setHeight?.(NumCast(this.props.Document[this.props.fieldKey + '_nativeHeight']) * (this.props.NativeDimScaling?.() || 1));
+ this._props.layoutDoc._nativeHeight = NumCast(this._props.Document[this._props.fieldKey + '_nativeHeight']);
+ this._props.setHeight?.(NumCast(this._props.Document[this._props.fieldKey + '_nativeHeight']) * (this._props.NativeDimScaling?.() || 1));
}
}
);
this._disposers.selected = reaction(
- () => this.props.isSelected(),
- selected => {
- // if (!selected) {
- // Array.from(this._savedAnnotations.values()).forEach(v => v.forEach(a => a.remove()));
- // Array.from(this._savedAnnotations.keys()).forEach(k => this._savedAnnotations.set(k, []));
- // }
- SelectionManager.Views().length === 1 && this.setupPdfJsViewer();
- },
+ () => this._props.isSelected(),
+ selected => SelectionManager.Views.length === 1 && this.setupPdfJsViewer(),
{ fireImmediately: true }
);
this._disposers.curPage = reaction(
- () => Cast(this.props.Document._layout_curPage, 'number', null),
+ () => Cast(this._props.Document._layout_curPage, 'number', null),
page => page !== undefined && page !== this._pdfViewer?.currentPageNumber && this.gotoPage(page),
{ fireImmediately: true }
);
- };
+ }
componentWillUnmount = () => {
Object.values(this._disposers).forEach(disposer => disposer?.());
@@ -135,7 +130,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
};
copy = (e: ClipboardEvent) => {
- if (this.props.isContentActive() && e.clipboardData) {
+ if (this._props.isContentActive() && e.clipboardData) {
e.clipboardData.setData('text/plain', this._selectionText);
const anchor = this._getAnchor(undefined, false);
if (anchor) {
@@ -151,18 +146,18 @@ export class PDFViewer extends React.Component<IViewerProps> {
@action
initialLoad = async () => {
if (this._pageSizes.length === 0) {
- this._pageSizes = Array<{ width: number; height: number }>(this.props.pdf.numPages);
+ this._pageSizes = Array<{ width: number; height: number }>(this._props.pdf.numPages);
await Promise.all(
this._pageSizes.map((val, i) =>
- this.props.pdf.getPage(i + 1).then(
+ this._props.pdf.getPage(i + 1).then(
action((page: Pdfjs.PDFPageProxy) => {
const page0or180 = page.rotate === 0 || page.rotate === 180;
this._pageSizes.splice(i, 1, {
width: page.view[page0or180 ? 2 : 3] - page.view[page0or180 ? 0 : 1],
height: page.view[page0or180 ? 3 : 2] - page.view[page0or180 ? 1 : 0],
});
- if (i === this.props.pdf.numPages - 1) {
- this.props.loaded?.(page.view[page0or180 ? 2 : 3] - page.view[page0or180 ? 0 : 1], page.view[page0or180 ? 3 : 2] - page.view[page0or180 ? 1 : 0], this.props.pdf.numPages);
+ if (i === this._props.pdf.numPages - 1) {
+ this._props.loaded?.(page.view[page0or180 ? 2 : 3] - page.view[page0or180 ? 0 : 1], page.view[page0or180 ? 3 : 2] - page.view[page0or180 ? 1 : 0], this._props.pdf.numPages);
}
})
)
@@ -176,31 +171,30 @@ export class PDFViewer extends React.Component<IViewerProps> {
// scrolls to focus on a nested annotation document. if this is part a link preview then it will jump to the scroll location,
// otherwise it will scroll smoothly.
- scrollFocus = (doc: Doc, scrollTop: number, options: DocFocusOptions) => {
+ scrollFocus = (doc: Doc, scrollTop: number, options: FocusViewOptions) => {
const mainCont = this._mainCont.current;
let focusSpeed: Opt<number>;
- if (doc !== this.props.rootDoc && mainCont) {
- const windowHeight = this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1);
- const scrollTo = Utils.scrollIntoView(scrollTop, doc[Height](), NumCast(this.props.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, this._scrollHeight);
- if (scrollTo !== undefined && scrollTo !== this.props.layoutDoc._layout_scrollTop) {
+ if (doc !== this._props.Document && mainCont) {
+ const windowHeight = this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1);
+ const scrollTo = Utils.scrollIntoView(scrollTop, doc[Height](), NumCast(this._props.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, this._scrollHeight);
+ if (scrollTo !== undefined && scrollTo !== this._props.layoutDoc._layout_scrollTop) {
if (!this._pdfViewer) this._initialScroll = { loc: scrollTo, easeFunc: options.easeFunc };
else if (!options.instant) this._scrollStopper = smoothScroll((focusSpeed = options.zoomTime ?? 500), mainCont, scrollTo, options.easeFunc, this._scrollStopper);
else this._mainCont.current?.scrollTo({ top: Math.abs(scrollTo || 0) });
}
} else {
- this._initialScroll = { loc: NumCast(this.props.layoutDoc._layout_scrollTop), easeFunc: options.easeFunc };
+ this._initialScroll = { loc: NumCast(this._props.layoutDoc._layout_scrollTop), easeFunc: options.easeFunc };
}
return focusSpeed;
};
- crop = (region: Doc | undefined, addCrop?: boolean) => this.props.crop(region, addCrop);
- brushView = (view: { width: number; height: number; panX: number; panY: number }, transTime: number) => this._setBrushViewer?.(view, transTime);
+ crop = (region: Doc | undefined, addCrop?: boolean) => this._props.crop(region, addCrop);
@action
setupPdfJsViewer = async () => {
if (this._viewerIsSetup) return;
this._viewerIsSetup = true;
this._showWaiting = true;
- this.props.setPdfViewer(this);
+ this._props.setPdfViewer(this);
await this.initialLoad();
this.createPdfViewer();
@@ -208,22 +202,22 @@ export class PDFViewer extends React.Component<IViewerProps> {
pagesinit = () => {
if (this._pdfViewer._setDocumentViewerElement?.offsetParent) {
- runInAction(() => (this._pdfViewer.currentScaleValue = this.props.layoutDoc._freeform_scale = 1));
- this.gotoPage(NumCast(this.props.Document._layout_curPage, 1));
+ runInAction(() => (this._pdfViewer.currentScaleValue = this._props.layoutDoc._freeform_scale = 1));
+ this.gotoPage(NumCast(this._props.Document._layout_curPage, 1));
}
document.removeEventListener('pagesinit', this.pagesinit);
var quickScroll: { loc?: string; easeFunc?: 'ease' | 'linear' } | undefined = { loc: this._initialScroll ? this._initialScroll.loc?.toString() : '', easeFunc: this._initialScroll ? this._initialScroll.easeFunc : undefined };
this._disposers.scale = reaction(
- () => NumCast(this.props.layoutDoc._freeform_scale, 1),
+ () => NumCast(this._props.layoutDoc._freeform_scale, 1),
scale => (this._pdfViewer.currentScaleValue = scale),
{ fireImmediately: true }
);
this._disposers.scroll = reaction(
- () => Math.abs(NumCast(this.props.Document._layout_scrollTop)),
+ () => Math.abs(NumCast(this._props.Document._layout_scrollTop)),
pos => {
if (!this._ignoreScroll) {
this._showWaiting && this.setupPdfJsViewer();
- const viewTrans = quickScroll?.loc ?? StrCast(this.props.Document._viewTransition);
+ const viewTrans = quickScroll?.loc ?? StrCast(this._props.Document._viewTransition);
const durationMiliStr = viewTrans.match(/([0-9]*)ms/);
const durationSecStr = viewTrans.match(/([0-9.]*)s/);
const duration = durationMiliStr ? Number(durationMiliStr[1]) : durationSecStr ? Number(durationSecStr[1]) * 1000 : 0;
@@ -264,7 +258,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
document.removeEventListener('copy', this.copy);
document.addEventListener('copy', this.copy);
- const eventBus = new PDFJSViewer.EventBus(true);
+ const eventBus = new PDFJSViewer.EventBus();
eventBus._on('pagesinit', this.pagesinit);
eventBus._on(
'pagerendered',
@@ -274,15 +268,14 @@ export class PDFViewer extends React.Component<IViewerProps> {
const pdfFindController = new PDFJSViewer.PDFFindController({ linkService: pdfLinkService, eventBus });
this._pdfViewer = new PDFJSViewer.PDFViewer({
container: this._mainCont.current,
- viewer: this._viewer.current,
+ viewer: this._viewer.current || undefined,
linkService: pdfLinkService,
findController: pdfFindController,
- renderer: 'canvas',
eventBus,
});
pdfLinkService.setViewer(this._pdfViewer);
- pdfLinkService.setDocument(this.props.pdf, null);
- this._pdfViewer.setDocument(this.props.pdf);
+ pdfLinkService.setDocument(this._props.pdf, null);
+ this._pdfViewer.setDocument(this._props.pdf);
}
@action
@@ -310,18 +303,18 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
};
- @observable private _scrollTimer: any;
+ @observable private _scrollTimer: any = undefined;
onScroll = (e: React.UIEvent<HTMLElement>) => {
if (this._mainCont.current && !this._forcedScroll) {
this._ignoreScroll = true; // the pdf scrolled, so we need to tell the Doc to scroll but we don't want the doc to then try to set the PDF scroll pos (which would interfere with the smooth scroll animation)
- if (!LinkDocPreview.LinkInfo) {
- this.props.layoutDoc._layout_scrollTop = this._mainCont.current.scrollTop;
+ if (!LinkInfo.Instance?.LinkInfo) {
+ this._props.layoutDoc._layout_scrollTop = this._mainCont.current.scrollTop;
}
this._ignoreScroll = false;
if (this._scrollTimer) clearTimeout(this._scrollTimer); // wait until a scrolling pause, then create an anchor to audio
this._scrollTimer = setTimeout(() => {
- DocUtils.MakeLinkToActiveAudio(() => this.props.DocumentView?.().ComponentView?.getAnchor!(true)!, false);
+ DocUtils.MakeLinkToActiveAudio(() => this._props.pdfBox.getAnchor(true)!, false);
this._scrollTimer = undefined;
}, 200);
}
@@ -371,24 +364,21 @@ export class PDFViewer extends React.Component<IViewerProps> {
// if alt+left click, drag and annotate
this._downX = e.clientX;
this._downY = e.clientY;
- if ((this.props.Document._freeform_scale || 1) !== 1) return;
- if ((e.button !== 0 || e.altKey) && this.props.isContentActive(true)) {
- this._setPreviewCursor?.(e.clientX, e.clientY, true, false, this.props.Document);
+ if ((this._props.Document._freeform_scale || 1) !== 1) return;
+ if ((e.button !== 0 || e.altKey) && this._props.isContentActive()) {
+ this._setPreviewCursor?.(e.clientX, e.clientY, true, false, this._props.Document);
}
- if (!e.altKey && e.button === 0 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
- this.props.select(false);
+ if (!e.altKey && e.button === 0 && this._props.isContentActive() && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
+ this._props.select(false);
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
- this._marqueeing = [e.clientX, e.clientY];
+ this._marqueeref.current?.onInitiateSelection([e.clientX, e.clientY]);
this.isAnnotating = true;
const target = e.target as any;
if (e.target && (target.className.includes('endOfContent') || (target.parentElement.className !== 'textLayer' && target.parentElement.parentElement?.className !== 'textLayer'))) {
this._textSelecting = false;
} else {
// if textLayer is hit, then we select text instead of using a marquee so clear out the marquee.
- setTimeout(
- action(() => (this._marqueeing = undefined)),
- 100
- ); // bcz: hack .. anchor menu is setup within MarqueeAnnotator so we need to at least create the marqueeAnnotator even though we aren't using it.
+ setTimeout(() => this._marqueeref.current?.onTerminateSelection(), 100); // bcz: hack .. anchor menu is setup within MarqueeAnnotator so we need to at least create the marqueeAnnotator even though we aren't using it.
this._styleRule = addStyleSheetRule(PDFViewer._annotationStyle, 'htmlAnnotation', { 'pointer-events': 'none' });
document.addEventListener('pointerup', this.onSelectEnd);
@@ -400,15 +390,16 @@ export class PDFViewer extends React.Component<IViewerProps> {
finishMarquee = (x?: number, y?: number) => {
this._getAnchor = AnchorMenu.Instance?.GetAnchor;
this.isAnnotating = false;
- this._marqueeing = undefined;
+ this._marqueeref.current?.onTerminateSelection();
this._textSelecting = true;
};
@action
onSelectEnd = (e: PointerEvent): void => {
+ this._getAnchor = AnchorMenu.Instance?.GetAnchor;
this.isAnnotating = false;
clearStyleSheetRules(PDFViewer._annotationStyle);
- this.props.select(false);
+ this._props.select(false);
document.removeEventListener('pointerup', this.onSelectEnd);
const sel = window.getSelection();
@@ -423,29 +414,32 @@ export class PDFViewer extends React.Component<IViewerProps> {
// Changing which document to add the annotation to (the currently selected PDF)
GPTPopup.Instance.setSidebarId('data_sidebar');
- GPTPopup.Instance.addDoc = this.props.sidebarAddDoc;
+ GPTPopup.Instance.addDoc = this._props.sidebarAddDoc;
};
@action
createTextAnnotation = (sel: Selection, selRange: Range) => {
if (this._mainCont.current) {
+ this._mainCont.current.style.transform = `rotate(${NumCast(this._props.pdfBox.ScreenToLocalBoxXf().RotateDeg)}deg)`;
const boundingRect = this._mainCont.current.getBoundingClientRect();
const clientRects = selRange.getClientRects();
for (let i = 0; i < clientRects.length; i++) {
const rect = clientRects.item(i);
- if (rect?.width && rect.width < this._mainCont.current.clientWidth / this.props.ScreenToLocalTransform().Scale) {
+ if (rect && rect?.width && rect.width < this._mainCont.current.clientWidth / this._props.ScreenToLocalTransform().Scale) {
const scaleX = this._mainCont.current.offsetWidth / boundingRect.width;
- const pdfScale = NumCast(this.props.layoutDoc._freeform_scale, 1);
+ const scaleY = this._mainCont.current.offsetHeight / boundingRect.height;
+ const pdfScale = NumCast(this._props.layoutDoc._freeform_scale, 1);
const annoBox = document.createElement('div');
annoBox.className = 'marqueeAnnotator-annotationBox';
// transforms the positions from screen onto the pdf div
- annoBox.style.top = (((rect.top - boundingRect.top) * scaleX) / pdfScale + this._mainCont.current.scrollTop).toString();
annoBox.style.left = (((rect.left - boundingRect.left) * scaleX) / pdfScale).toString();
- annoBox.style.width = ((rect.width * this._mainCont.current.offsetWidth) / boundingRect.width / pdfScale).toString();
- annoBox.style.height = ((rect.height * this._mainCont.current.offsetHeight) / boundingRect.height / pdfScale).toString();
+ annoBox.style.top = (((rect.top - boundingRect.top) * scaleY) / pdfScale + this._mainCont.current.scrollTop).toString();
+ annoBox.style.width = ((rect.width * scaleX) / pdfScale).toString();
+ annoBox.style.height = ((rect.height * scaleY) / pdfScale).toString();
this._annotationLayer.current && MarqueeAnnotator.previewNewAnnotation(this._savedAnnotations, this._annotationLayer.current, annoBox, this.getPageFromScroll(rect.top));
}
}
+ this._mainCont.current!.style.transform = '';
}
this._selectionContent = selRange.cloneContents();
this._selectionText = this._selectionContent?.textContent || '';
@@ -463,69 +457,57 @@ export class PDFViewer extends React.Component<IViewerProps> {
onClick = (e: React.MouseEvent) => {
this._scrollStopper?.();
if (this._setPreviewCursor && e.button === 0 && Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD) {
- this._setPreviewCursor(e.clientX, e.clientY, false, false, this.props.Document);
+ this._setPreviewCursor(e.clientX, e.clientY, false, false, this._props.Document);
}
// e.stopPropagation(); // bcz: not sure why this was here. We need to allow the DocumentView to get clicks to process doubleClicks
};
setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => (this._setPreviewCursor = func);
- setBrushViewer = (func?: (view: { width: number; height: number; panX: number; panY: number }, transTime: number) => void) => (this._setBrushViewer = func);
@action
onZoomWheel = (e: React.WheelEvent) => {
- if (this.props.isContentActive(true)) {
+ if (this._props.isContentActive()) {
e.stopPropagation();
if (e.ctrlKey) {
const curScale = Number(this._pdfViewer.currentScaleValue);
this._pdfViewer.currentScaleValue = Math.max(1, Math.min(10, curScale - (curScale * e.deltaY) / 1000));
- this.props.layoutDoc._freeform_scale = Number(this._pdfViewer.currentScaleValue);
+ this._props.layoutDoc._freeform_scale = Number(this._pdfViewer.currentScaleValue);
}
}
};
pointerEvents = () =>
- this.props.isContentActive() && !MarqueeOptionsMenu.Instance.isShown()
+ this._props.isContentActive() && !MarqueeOptionsMenu.Instance.isShown()
? 'all' //
: 'none';
@computed get annotationLayer() {
const inlineAnnos = this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).filter(anno => !anno.hidden);
return (
- <div className="pdfViewerDash-annotationLayer" style={{ height: Doc.NativeHeight(this.props.Document), transform: `scale(${NumCast(this.props.layoutDoc._freeform_scale, 1)})` }} ref={this._annotationLayer}>
+ <div className="pdfViewerDash-annotationLayer" style={{ height: Doc.NativeHeight(this._props.Document), transform: `scale(${NumCast(this._props.layoutDoc._freeform_scale, 1)})` }} ref={this._annotationLayer}>
{inlineAnnos.map(anno => (
- <Annotation {...this.props} fieldKey={this.props.fieldKey + '_annotations'} pointerEvents={this.pointerEvents} showInfo={this.showInfo} dataDoc={this.props.dataDoc} anno={anno} key={`${anno[Id]}-annotation`} />
+ <Annotation {...this._props} fieldKey={this._props.fieldKey + '_annotations'} pointerEvents={this.pointerEvents} dataDoc={this._props.dataDoc} anno={anno} key={`${anno[Id]}-annotation`} />
))}
</div>
);
}
- @computed get overlayInfo() {
- return !this._overlayAnnoInfo ? null : (
- <div className="pdfViewerDash-overlayAnno" style={{ top: NumCast(this._overlayAnnoInfo.y), left: NumCast(this._overlayAnnoInfo.x) }}>
- <div className="pdfViewerDash-overlayAnno" style={{ right: -50, background: SharingManager.Instance.users.find(users => users.user.email === this._overlayAnnoInfo!.author)?.userColor }}>
- {this._overlayAnnoInfo.author + ' ' + Field.toString(this._overlayAnnoInfo.author_date as Field)}
- </div>
- </div>
- );
- }
-
getScrollHeight = () => this._scrollHeight;
- showInfo = action((anno: Opt<Doc>) => (this._overlayAnnoInfo = anno));
- scrollXf = () => (this._mainCont.current ? this.props.ScreenToLocalTransform().translate(0, NumCast(this.props.layoutDoc._layout_scrollTop)) : this.props.ScreenToLocalTransform());
- overlayTransform = () => this.scrollXf().scale(1 / NumCast(this.props.layoutDoc._freeform_scale, 1));
- panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1);
- panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1);
- transparentFilter = () => [...this.props.childFilters(), Utils.IsTransparentFilter()];
- opaqueFilter = () => [...this.props.childFilters(), Utils.noDragsDocFilter, ...(DragManager.docsBeingDragged.length && this.props.isContentActive() ? [] : [Utils.IsOpaqueFilter()])];
- childStyleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string): any => {
+ scrollXf = () => this._props.ScreenToLocalTransform().translate(0, this._mainCont.current ? NumCast(this._props.layoutDoc._layout_scrollTop) : 0);
+ overlayTransform = () => this.scrollXf().scale(1 / NumCast(this._props.layoutDoc._freeform_scale, 1));
+ panelWidth = () => this._props.PanelWidth() / (this._props.NativeDimScaling?.() || 1);
+ panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1);
+ transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter];
+ opaqueFilter = () => [...this._props.childFilters(), Utils.noDragDocsFilter, ...(SnappingManager.CanEmbed && this._props.isContentActive() ? [] : [Utils.OpaqueBackgroundFilter])];
+ childStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string): any => {
if (doc instanceof Doc && property === StyleProp.PointerEvents) {
- if (this.inlineTextAnnotations.includes(doc) || this.props.isContentActive() === false) return 'none';
+ if (this.inlineTextAnnotations.includes(doc) || this._props.isContentActive() === false) return 'none';
const isInk = doc.layout_isSvg && !props?.LayoutTemplateString;
return isInk ? 'visiblePainted' : 'all';
}
- return this.props.styleProvider?.(doc, props, property);
+ return this._props.styleProvider?.(doc, props, property);
};
- childPointerEvents = () => (this.props.isContentActive() !== false ? 'all' : 'none');
+ childPointerEvents = () => (this._props.isContentActive() !== false ? 'all' : 'none');
renderAnnotations = (childFilters: () => string[], mixBlendMode?: any, display?: string) => (
<div
className="pdfViewerDash-overlay"
@@ -535,18 +517,17 @@ export class PDFViewer extends React.Component<IViewerProps> {
pointerEvents: Doc.ActiveTool !== InkTool.None ? 'all' : undefined,
}}>
<CollectionFreeFormView
- {...this.props}
+ {...this._props}
NativeWidth={returnZero}
NativeHeight={returnZero}
- setContentView={emptyFunction} // override setContentView to do nothing
- pointerEvents={this.props.isContentActive() && (SnappingManager.GetIsDragging() || Doc.ActiveTool !== InkTool.None) ? returnAll : returnNone} // freeform view doesn't get events unless something is being dragged onto it.
+ setContentViewBox={emptyFunction} // override setContentView to do nothing
+ pointerEvents={this._props.isContentActive() && (SnappingManager.IsDragging || Doc.ActiveTool !== InkTool.None) ? returnAll : returnNone} // freeform view doesn't get events unless something is being dragged onto it.
childPointerEvents={this.childPointerEvents} // but freeform children need to get events to allow text editing, etc
- renderDepth={this.props.renderDepth + 1}
+ renderDepth={this._props.renderDepth + 1}
isAnnotationOverlay={true}
- fieldKey={this.props.fieldKey + '_annotations'}
+ fieldKey={this._props.fieldKey + '_annotations'}
getScrollHeight={this.getScrollHeight}
setPreviewCursor={this.setPreviewCursor}
- setBrushViewer={this.setBrushViewer}
PanelHeight={this.panelHeight}
PanelWidth={this.panelWidth}
ScreenToLocalTransform={this.overlayTransform}
@@ -554,64 +535,65 @@ export class PDFViewer extends React.Component<IViewerProps> {
isAnnotationOverlayScrollable={true}
childFilters={childFilters}
select={emptyFunction}
- bringToFront={emptyFunction}
styleProvider={this.childStyleProvider}
/>
</div>
);
@computed get overlayTransparentAnnotations() {
- const transparentChildren = DocUtils.FilterDocs(DocListCast(this.props.dataDoc[this.props.fieldKey + '_annotations']), this.transparentFilter(), []);
- return !transparentChildren.length ? null : this.renderAnnotations(this.transparentFilter, 'multiply', DragManager.docsBeingDragged.length && this.props.isContentActive() ? 'none' : undefined);
+ const transparentChildren = DocUtils.FilterDocs(DocListCast(this._props.dataDoc[this._props.fieldKey + '_annotations']), this.transparentFilter(), []);
+ return !transparentChildren.length ? null : this.renderAnnotations(this.transparentFilter, 'multiply', SnappingManager.CanEmbed && this._props.isContentActive() ? 'none' : undefined);
}
@computed get overlayOpaqueAnnotations() {
return this.renderAnnotations(this.opaqueFilter, this.allAnnotations.some(anno => anno.mixBlendMode) ? 'hard-light' : undefined);
}
@computed get overlayLayer() {
return (
- <div style={{ pointerEvents: this.props.isContentActive() && SnappingManager.GetIsDragging() ? 'all' : 'none' }}>
+ <div style={{ pointerEvents: this._props.isContentActive() && SnappingManager.IsDragging ? 'all' : 'none' }}>
{this.overlayTransparentAnnotations}
{this.overlayOpaqueAnnotations}
</div>
);
}
@computed get pdfViewerDiv() {
- return <div className={'pdfViewerDash-text' + (this.props.pointerEvents?.() !== 'none' && this._textSelecting && this.props.isContentActive() ? '-selected' : '')} ref={this._viewer} />;
+ return <div className={'pdfViewerDash-text' + (this._props.pointerEvents?.() !== 'none' && this._textSelecting && this._props.isContentActive() ? '-selected' : '')} ref={this._viewer} />;
}
savedAnnotations = () => this._savedAnnotations;
+ addDocumentWrapper = (doc: Doc | Doc[]) => this._props.addDocument!(doc);
render() {
TraceMobx();
return (
<div className="pdfViewer-content">
<div
- className={`pdfViewerDash${this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' ? '-interactive' : ''}`}
+ className={`pdfViewerDash${this._props.isContentActive() && this._props.pointerEvents?.() !== 'none' ? '-interactive' : ''}`}
ref={this._mainCont}
onScroll={this.onScroll}
onWheel={this.onZoomWheel}
onPointerDown={this.onPointerDown}
onClick={this.onClick}
style={{
- overflowX: NumCast(this.props.layoutDoc._freeform_scale, 1) !== 1 ? 'scroll' : undefined,
- height: !this.props.Document._layout_fitWidth && window.screen.width > 600 ? Doc.NativeHeight(this.props.Document) : `100%`,
+ overflowX: NumCast(this._props.layoutDoc._freeform_scale, 1) !== 1 ? 'scroll' : undefined,
+ height: !this._props.Document._layout_fitWidth && window.screen.width > 600 ? Doc.NativeHeight(this._props.Document) : `100%`,
}}>
{this.pdfViewerDiv}
{this.annotationLayer}
{this.overlayLayer}
- {this.overlayInfo}
{this._showWaiting ? <img className="pdfViewerDash-waiting" src={'/assets/loading.gif'} /> : null}
- {!this._marqueeing || !this._mainCont.current || !this._annotationLayer.current ? null : (
+ {!this._mainCont.current || !this._annotationLayer.current ? null : (
<MarqueeAnnotator
- rootDoc={this.props.rootDoc}
+ ref={this._marqueeref}
+ Document={this._props.Document}
getPageFromScroll={this.getPageFromScroll}
- anchorMenuClick={this.props.anchorMenuClick}
+ anchorMenuClick={this._props.anchorMenuClick}
scrollTop={0}
- down={this._marqueeing}
- addDocument={(doc: Doc | Doc[]) => this.props.addDocument!(doc)}
- docView={this.props.docViewPath().lastElement()}
+ isNativeScaled={true}
+ annotationLayerScrollTop={NumCast(this._props.Document._layout_scrollTop)}
+ addDocument={this.addDocumentWrapper}
+ docView={this._props.pdfBox.DocumentView!}
finishMarquee={this.finishMarquee}
savedAnnotations={this.savedAnnotations}
selectionText={this.selectionText}
annotationLayer={this._annotationLayer.current}
- mainCont={this._mainCont.current}
+ marqueeContainer={this._mainCont.current}
anchorMenuCrop={this._textSelecting ? undefined : this.crop}
/>
)}