aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/pdf/PDFViewer.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/pdf/PDFViewer.tsx')
-rw-r--r--src/client/views/pdf/PDFViewer.tsx84
1 files changed, 33 insertions, 51 deletions
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 167421a4a..fc2567fbc 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -1,9 +1,10 @@
import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as Pdfjs from 'pdfjs-dist';
+import { GlobalWorkerOptions } from 'pdfjs-dist/build/pdf.mjs';
import * as PDFJSViewer from 'pdfjs-dist/web/pdf_viewer.mjs';
-import 'pdfjs-dist/webpack.mjs'; // sets the PDF workerSrc
import * as React from 'react';
+import ReactLoading from 'react-loading';
import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, returnAll, returnFalse, returnNone, returnZero, smoothScroll } from '../../../ClientUtils';
import { CreateLinkToActiveAudio, Doc, DocListCast, Opt } from '../../../fields/Doc';
import { DocData, Height } from '../../../fields/DocSymbols';
@@ -11,9 +12,10 @@ import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { Cast, NumCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, numberRange } from '../../../Utils';
+import { emptyFunction, numberRange, unimplementedFunction } from '../../../Utils';
import { DocUtils } from '../../documents/DocUtils';
import { SnappingManager } from '../../util/SnappingManager';
+import { Transform } from '../../util/Transform';
import { MarqueeOptionsMenu } from '../collections/collectionFreeForm';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import { MarqueeAnnotator } from '../MarqueeAnnotator';
@@ -28,13 +30,13 @@ import { AnchorMenu } from './AnchorMenu';
import { Annotation } from './Annotation';
import { GPTPopup } from './GPTPopup/GPTPopup';
import './PDFViewer.scss';
-import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT';
-import ReactLoading from 'react-loading';
-import { Transform } from '../../util/Transform';
+import { DocumentViewProps } from '../nodes/DocumentContentsView';
+if (window?.Worker) GlobalWorkerOptions.workerSrc = 'files/node_modules/pdfjs-dist/build/pdf.worker.min.mjs'; // npm start/etc use copyfiles to copy the worker from the pdfjs-dist package to the public folder
+export * from 'pdfjs-dist/build/pdf.mjs';
interface IViewerProps extends FieldViewProps {
pdfBox: PDFBox;
- Document: Doc;
+ Doc: Doc;
dataDoc: Doc;
layoutDoc: Doc;
fieldKey: string;
@@ -53,7 +55,7 @@ interface IViewerProps extends FieldViewProps {
*/
@observer
export class PDFViewer extends ObservableReactComponent<IViewerProps> {
- static _annotationStyle = addStyleSheet();
+ static _annotationStyle = addStyleSheet().sheet;
constructor(props: IViewerProps) {
super(props);
@@ -112,8 +114,8 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
() => this._props.layoutDoc._layout_autoHeight,
layoutAutoHeight => {
if (layoutAutoHeight) {
- 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.Doc[this._props.fieldKey + '_nativeHeight']);
+ this._props.setHeight?.(NumCast(this._props.Doc[this._props.fieldKey + '_nativeHeight']) * (this._props.NativeDimScaling?.() || 1));
}
}
);
@@ -124,7 +126,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
{ fireImmediately: true }
);
this._disposers.curPage = reaction(
- () => Cast(this._props.Document._layout_curPage, 'number', null),
+ () => Cast(this._props.Doc._layout_curPage, 'number', null),
page => page !== undefined && page !== this._pdfViewer?.currentPageNumber && this.gotoPage(page),
{ fireImmediately: true }
);
@@ -132,7 +134,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
componentWillUnmount = () => {
Object.values(this._disposers).forEach(disposer => disposer?.());
- document.removeEventListener('copy', this.copy);
+ document.removeEventListener('copy', this.copy, true);
};
copy = (e: ClipboardEvent) => {
@@ -144,6 +146,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
e.clipboardData.setData('dash/pdfAnchor', anchor[DocData][Id]);
}
e.preventDefault();
+ e.stopPropagation();
}
};
@@ -180,7 +183,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
scrollFocus = (doc: Doc, scrollTop: number, options: FocusViewOptions) => {
const mainCont = this._mainCont.current;
let focusSpeed: Opt<number>;
- if (doc !== this._props.Document && mainCont) {
+ if (doc !== this._props.Doc && mainCont) {
const windowHeight = this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1);
const scrollTo = ClientUtils.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) {
@@ -215,11 +218,11 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
{ fireImmediately: true }
);
this._disposers.scroll = reaction(
- () => Math.abs(NumCast(this._props.Document._layout_scrollTop)),
+ () => Math.abs(NumCast(this._props.Doc._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.Doc._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;
@@ -260,16 +263,11 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
}
return;
}
- document.removeEventListener('copy', this.copy);
- document.addEventListener('copy', this.copy);
+ document.removeEventListener('copy', this.copy, true);
+ document.addEventListener('copy', this.copy, true);
const eventBus = new PDFJSViewer.EventBus();
eventBus._on('pagesinit', this.pagesinit);
- eventBus._on(
- 'pagerendered',
- action(() => {
- this._showWaiting = false;
- })
- );
+ eventBus._on('pagerendered',action(() => (this._showWaiting = false))); // prettier-ignore
const pdfLinkService = new PDFJSViewer.PDFLinkService({ eventBus });
const pdfFindController = new PDFJSViewer.PDFFindController({ linkService: pdfLinkService, eventBus });
this._pdfViewer = new PDFJSViewer.PDFViewer({
@@ -370,9 +368,9 @@ export class PDFViewer extends ObservableReactComponent<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 ((this._props.Doc._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);
+ this._setPreviewCursor?.(e.clientX, e.clientY, true, false, this._props.Doc);
}
if (!e.altKey && e.button === 0 && this._props.isContentActive() && Doc.ActiveTool !== InkTool.Ink) {
this._props.select(false);
@@ -392,25 +390,9 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
}
};
- /**
- * Create a flashcard pile based on the selected text of a pdf.
- */
- gptPDFFlashcards = async () => {
- const queryText = this._selectionText;
- this._loading = true;
- try {
- const res = await gptAPICall(queryText, GPTCallType.FLASHCARD);
-
- AnchorMenu.Instance.transferToFlashcard(res || 'Something went wrong', NumCast(this._props.layoutDoc['x']), NumCast(this._props.layoutDoc['y']));
- this._selectionText = '';
- } catch (err) {
- console.error(err);
- }
- this._loading = false;
- };
-
@action
finishMarquee = (/* x?: number, y?: number */) => {
+ AnchorMenu.Instance.makeLabels = unimplementedFunction;
this._getAnchor = AnchorMenu.Instance?.GetAnchor;
this.isAnnotating = false;
this._marqueeref.current?.onTerminateSelection();
@@ -429,7 +411,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
if (sel) {
AnchorMenu.Instance.setSelectedText(sel.toString());
- AnchorMenu.Instance.setLocation(NumCast(this._props.layoutDoc['x']), NumCast(this._props.layoutDoc['y']));
+ AnchorMenu.Instance.setLocation(NumCast(this._props.layoutDoc.x), NumCast(this._props.layoutDoc.y));
}
if (sel?.type === 'Range') {
@@ -441,14 +423,14 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
GPTPopup.Instance.addDoc = this._props.sidebarAddDoc;
// allows for creating collection
AnchorMenu.Instance.addToCollection = this._props.DocumentView?.()._props.addDocument;
- AnchorMenu.Instance.gptFlashcards = this.gptPDFFlashcards;
+ AnchorMenu.Instance.makeLabels = unimplementedFunction;
AnchorMenu.Instance.AddDrawingAnnotation = this.addDrawingAnnotation;
};
addDrawingAnnotation = (drawing: Doc) => {
- // drawing[DocData].x = this._props.pdfBox.ScreenToLocalBoxXf().TranslateX
+ // drawing.x = this._props.pdfBox.ScreenToLocalBoxXf().TranslateX
// const scaleX = this._mainCont.current.offsetWidth / boundingRect.width;
- drawing.y = NumCast(drawing.y) + NumCast(this._props.Document.layout_scrollTop);
+ drawing.y = NumCast(drawing.y) + NumCast(this._props.Doc.layout_scrollTop);
this._props.addDocument?.(drawing);
};
@@ -493,7 +475,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
onClick = (e: React.MouseEvent) => {
this._scrollStopper?.();
if (this._setPreviewCursor && e.button === 0 && Math.abs(e.clientX - this._downX) < ClientUtils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < ClientUtils.DRAG_THRESHOLD) {
- this._setPreviewCursor(e.clientX, e.clientY, false, false, this._props.Document);
+ this._setPreviewCursor(e.clientX, e.clientY, false, false, this._props.Doc);
}
// e.stopPropagation(); // bcz: not sure why this was here. We need to allow the DocumentView to get clicks to process doubleClicks
};
@@ -521,7 +503,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
@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.Doc), 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} containerDataDoc={this._props.dataDoc} annoDoc={anno} key={`${anno[Id]}-annotation`} />
))}
@@ -536,7 +518,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1);
transparentFilter = () => [...this._props.childFilters(), ClientUtils.TransparentBackgroundFilter];
opaqueFilter = () => [...this._props.childFilters(), ClientUtils.noDragDocsFilter, ...(SnappingManager.CanEmbed && this._props.isContentActive() ? [] : [ClientUtils.OpaqueBackgroundFilter])];
- childStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string) => {
+ childStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps & DocumentViewProps>, property: string) => {
if (doc instanceof Doc && property === StyleProp.PointerEvents) {
if (this.inlineTextAnnotations.includes(doc) || this._props.isContentActive() === false) return 'none';
const isInk = doc.layout_isSvg && !props?.LayoutTemplateString;
@@ -612,7 +594,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
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%`,
+ height: !this._props.Doc._layout_fitWidth && window.screen.width > 600 ? Doc.NativeHeight(this._props.Doc) : `100%`,
}}>
{this.pdfViewerDiv}
{this.annotationLayer}
@@ -621,12 +603,12 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
{!this._mainCont.current || !this._annotationLayer.current || !this.props.pdfBox.DocumentView ? null : (
<MarqueeAnnotator
ref={this._marqueeref}
- Document={this._props.Document}
+ Document={this._props.Doc}
getPageFromScroll={this.getPageFromScroll}
anchorMenuClick={this._props.anchorMenuClick}
scrollTop={0}
annotationLayerScaling={() => Pdfjs.PixelsPerInch.PDF_TO_CSS_UNITS}
- annotationLayerScrollTop={NumCast(this._props.Document._layout_scrollTop)}
+ annotationLayerScrollTop={NumCast(this._props.Doc._layout_scrollTop)}
addDocument={this.addDocumentWrapper}
docView={this.props.pdfBox.DocumentView}
screenTransform={this.screenToMarqueeXf}