diff options
Diffstat (limited to 'src/client/views/nodes/PDFBox.tsx')
-rw-r--r-- | src/client/views/nodes/PDFBox.tsx | 120 |
1 files changed, 60 insertions, 60 deletions
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 1035116d5..733febd2d 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -1,8 +1,9 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as Pdfjs from 'pdfjs-dist'; import 'pdfjs-dist/web/pdf_viewer.css'; +import * as React from 'react'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; @@ -31,7 +32,6 @@ import { FieldView, FieldViewProps } from './FieldView'; import { ImageBox } from './ImageBox'; import './PDFBox.scss'; import { PinProps, PresBox } from './trails'; -import React = require('react'); @observer export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps>() { @@ -52,7 +52,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps @observable private _pageControls = false; @computed get pdfUrl() { - return Cast(this.dataDoc[this.props.fieldKey], PdfField); + return Cast(this.dataDoc[this._props.fieldKey], PdfField); } @computed get pdfThumb() { return ImageCast(this.layoutDoc['thumb-frozen'], ImageCast(this.layoutDoc.thumb))?.url; @@ -60,6 +60,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps constructor(props: any) { super(props); + makeObservable(this); const nw = Doc.NativeWidth(this.Document, this.dataDoc) || 927; const nh = Doc.NativeHeight(this.Document, this.dataDoc) || 1200; !this.Document._layout_fitWidth && (this.Document._height = NumCast(this.Document._width) * (nh / nw)); @@ -97,11 +98,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps if (!region) return; const cropping = Doc.MakeCopy(region, true); Doc.GetProto(region).lockedPosition = true; - Doc.GetProto(region).title = 'region:' + this.rootDoc.title; + Doc.GetProto(region).title = 'region:' + this.Document.title; Doc.GetProto(region).followLinkToggle = true; this.addDocument(region); - const docViewContent = this.props.docViewPath().lastElement().ContentDiv!; + const docViewContent = this._props.docViewPath().lastElement().ContentDiv!; const newDiv = docViewContent.cloneNode(true) as HTMLDivElement; newDiv.style.width = NumCast(this.layoutDoc._width).toString(); newDiv.style.height = NumCast(this.layoutDoc._height).toString(); @@ -110,19 +111,19 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps const anchx = NumCast(cropping.x); const anchy = NumCast(cropping.y); - const anchw = NumCast(cropping._width) * (this.props.NativeDimScaling?.() || 1); - const anchh = NumCast(cropping._height) * (this.props.NativeDimScaling?.() || 1); + const anchw = NumCast(cropping._width) * (this._props.NativeDimScaling?.() || 1); + const anchh = NumCast(cropping._height) * (this._props.NativeDimScaling?.() || 1); const viewScale = 1; - cropping.title = 'crop: ' + this.rootDoc.title; - cropping.x = NumCast(this.rootDoc.x) + NumCast(this.rootDoc._width); - cropping.y = NumCast(this.rootDoc.y); + cropping.title = 'crop: ' + this.Document.title; + cropping.x = NumCast(this.Document.x) + NumCast(this.layoutDoc._width); + cropping.y = NumCast(this.Document.y); cropping._width = anchw; cropping._height = anchh; cropping.onClick = undefined; const croppingProto = Doc.GetProto(cropping); croppingProto.annotationOn = undefined; croppingProto.isDataDoc = true; - croppingProto.proto = Cast(this.rootDoc.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO + croppingProto.proto = Cast(this.Document.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO croppingProto.type = DocumentType.IMG; croppingProto.layout = ImageBox.LayoutString('data'); croppingProto.data = new ImageField(Utils.CorsProxy('http://www.cs.brown.edu/~bcz/noImage.png')); @@ -131,7 +132,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps if (addCrop) { DocUtils.MakeLink(region, cropping, { link_relationship: 'cropped image' }); } - this.props.bringToFront(cropping); + this._props.bringToFront(cropping); CreateImage( '', @@ -139,8 +140,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps htmlString, anchw, anchh, - (NumCast(region.y) * this.props.PanelWidth()) / NumCast(this.rootDoc[this.fieldKey + '_nativeWidth']), - (NumCast(region.x) * this.props.PanelWidth()) / NumCast(this.rootDoc[this.fieldKey + '_nativeWidth']), + (NumCast(region.y) * this._props.PanelWidth()) / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']), + (NumCast(region.x) * this._props.PanelWidth()) / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']), 4 ) .then((data_url: any) => { @@ -162,7 +163,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps updateIcon = () => { // currently we render pdf icons as text labels - const docViewContent = this.props.docViewPath().lastElement().ContentDiv!; + const docViewContent = this._props.docViewPath().lastElement().ContentDiv!; const filename = this.layoutDoc[Id] + '-icon' + new Date().getTime(); this._pdfViewer?._mainCont.current && CollectionFreeFormView.UpdateIcon( @@ -170,10 +171,10 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps docViewContent, NumCast(this.layoutDoc._width), NumCast(this.layoutDoc._height), - this.props.PanelWidth(), - this.props.PanelHeight(), + this._props.PanelWidth(), + this._props.PanelHeight(), NumCast(this.layoutDoc._layout_scrollTop), - NumCast(this.rootDoc[this.fieldKey + '_nativeHeight'], 1), + NumCast(this.dataDoc[this.fieldKey + '_nativeHeight'], 1), true, this.layoutDoc[Id] + '-icon', (iconFile: string, nativeWidth: number, nativeHeight: number) => { @@ -190,33 +191,33 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps Object.values(this._disposers).forEach(disposer => disposer?.()); } componentDidMount() { - this.props.setContentView?.(this); + this._props.setContentView?.(this); this._disposers.select = reaction( - () => this.props.isSelected(), + () => this._props.isSelected(), () => { document.removeEventListener('keydown', this.onKeyDown); - this.props.isSelected() && document.addEventListener('keydown', this.onKeyDown); + this._props.isSelected() && document.addEventListener('keydown', this.onKeyDown); }, { fireImmediately: true } ); this._disposers.scroll = reaction( - () => this.rootDoc.layout_scrollTop, + () => this.layoutDoc.layout_scrollTop, () => { - if (!(ComputedField.WithoutComputed(() => FieldValue(this.props.Document[this.SidebarKey + '_panY'])) instanceof ComputedField)) { - this.props.Document[this.SidebarKey + '_panY'] = ComputedField.MakeFunction('this.layout_scrollTop'); + if (!(ComputedField.WithoutComputed(() => FieldValue(this.Document[this.SidebarKey + '_panY'])) instanceof ComputedField)) { + this.Document[this.SidebarKey + '_panY'] = ComputedField.MakeFunction('this.layout_scrollTop'); } - this.props.Document[this.SidebarKey + '_freeform_scale'] = 1; - this.props.Document[this.SidebarKey + '_freeform_panX'] = 0; + this.layoutDoc[this.SidebarKey + '_freeform_scale'] = 1; + this.layoutDoc[this.SidebarKey + '_freeform_panX'] = 0; } ); } sidebarAddDocTab = (doc: Doc, where: OpenWhere) => { - if (DocListCast(this.props.Document[this.props.fieldKey + '_sidebar']).includes(doc) && !this.SidebarShown) { + if (DocListCast(this.Document[this._props.fieldKey + '_sidebar']).includes(doc) && !this.SidebarShown) { this.toggleSidebar(false); return true; } - return this.props.addDocTab(doc, where); + return this._props.addDocTab(doc, where); }; focus = (anchor: Doc, options: DocFocusOptions) => { this._initialScrollTarget = anchor; @@ -236,12 +237,12 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps } const docAnchor = () => Docs.Create.ConfigDocument({ - title: StrCast(this.rootDoc.title + '@' + NumCast(this.layoutDoc._layout_scrollTop)?.toFixed(0)), - annotationOn: this.rootDoc, + title: StrCast(this.Document.title + '@' + NumCast(this.layoutDoc._layout_scrollTop)?.toFixed(0)), + annotationOn: this.Document, }); const visibleAnchor = this._pdfViewer?._getAnchor?.(this._pdfViewer.savedAnnotations(), true); const anchor = visibleAnchor ?? docAnchor(); - PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: true, pannable: true } }, this.rootDoc); + PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: true, pannable: true } }, this.Document); anchor.text = ele?.textContent ?? ''; anchor.text_html = ele?.innerHTML; addAsAnnotation && this.addDocument(anchor); @@ -251,7 +252,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps @action loaded = (nw: number, nh: number, np: number) => { - this.dataDoc[this.props.fieldKey + '_numPages'] = np; + this.dataDoc[this._props.fieldKey + '_numPages'] = np; Doc.SetNativeWidth(this.dataDoc, Math.max(Doc.NativeWidth(this.dataDoc), (nw * 96) / 72)); Doc.SetNativeHeight(this.dataDoc, (nh * 96) / 72); this.layoutDoc._height = NumCast(this.layoutDoc._width) / (Doc.NativeAspect(this.dataDoc) || 1); @@ -276,7 +277,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps return true; }; public forwardPage = () => { - this.Document._layout_curPage = Math.min(NumCast(this.dataDoc[this.props.fieldKey + '_numPages']), (NumCast(this.Document._layout_curPage) || 1) + 1); + this.Document._layout_curPage = Math.min(NumCast(this.dataDoc[this._props.fieldKey + '_numPages']), (NumCast(this.Document._layout_curPage) || 1) + 1); return true; }; public gotoPage = (p: number) => (this.Document._layout_curPage = p); @@ -300,7 +301,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps setPdfViewer = (pdfViewer: PDFViewer) => { this._pdfViewer = pdfViewer; - const docView = this.props.DocumentView?.(); + const docView = this._props.DocumentView?.(); if (this._initialScrollTarget && docView) { this.focus(this._initialScrollTarget, { instant: true }); this._initialScrollTarget = undefined; @@ -321,13 +322,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps this, e, (e, down, delta) => { - const localDelta = this.props + const localDelta = this._props .ScreenToLocalTransform() - .scale(this.props.NativeDimScaling?.() || 1) + .scale(this._props.NativeDimScaling?.() || 1) .transformDirection(delta[0], delta[1]); const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']); const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth); - const ratio = (curNativeWidth + ((onButton ? 1 : -1) * localDelta[0]) / (this.props.NativeDimScaling?.() || 1)) / nativeWidth; + const ratio = (curNativeWidth + ((onButton ? 1 : -1) * localDelta[0]) / (this._props.NativeDimScaling?.() || 1)) / nativeWidth; if (ratio >= 1) { this.layoutDoc.nativeWidth = nativeWidth * ratio; onButton && (this.layoutDoc._width = NumCast(this.layoutDoc._width) + localDelta[0]); @@ -372,12 +373,12 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps ); const searchTitle = `${!this._searching ? 'Open' : 'Close'} Search Bar`; const curPage = NumCast(this.Document._layout_curPage) || 1; - return !this.props.isContentActive() || this._pdfViewer?.isAnnotating ? null : ( + return !this._props.isContentActive() || this._pdfViewer?.isAnnotating ? null : ( <div className="pdfBox-ui" onKeyDown={e => ([KeyCodes.BACKSPACE, KeyCodes.DELETE].includes(e.keyCode) ? e.stopPropagation() : true)} onPointerDown={e => e.stopPropagation()} - style={{ display: this.props.isContentActive() ? 'flex' : 'none' }}> + style={{ display: this._props.isContentActive() ? 'flex' : 'none' }}> <div className="pdfBox-overlayCont" onPointerDown={e => e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}> <button className="pdfBox-overlayButton" title={searchTitle} /> <input @@ -431,10 +432,10 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps if (!this.SidebarShown) return 0; if (this._previewWidth) return PDFBox.sidebarResizerWidth + PDFBox.openSidebarWidth; // return default sidebar if previewing (as in viewing a link target) const nativeDiff = NumCast(this.layoutDoc.nativeWidth) - Doc.NativeWidth(this.dataDoc); - return PDFBox.sidebarResizerWidth + nativeDiff * (this.props.NativeDimScaling?.() || 1); + return PDFBox.sidebarResizerWidth + nativeDiff * (this._props.NativeDimScaling?.() || 1); }; @undoBatch - toggleSidebarType = () => (this.rootDoc[this.SidebarKey + '_type_collection'] = this.rootDoc[this.SidebarKey + '_type_collection'] === CollectionViewType.Freeform ? CollectionViewType.Stacking : CollectionViewType.Freeform); + toggleSidebarType = () => (this.dataDoc[this.SidebarKey + '_type_collection'] = this.dataDoc[this.SidebarKey + '_type_collection'] === CollectionViewType.Freeform ? CollectionViewType.Stacking : CollectionViewType.Freeform); specificContextMenu = (e: React.MouseEvent): void => { const cm = ContextMenu.Instance; const options = cm.findByDescription('Options...'); @@ -450,11 +451,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps }; @computed get renderTitleBox() { - const classname = 'pdfBox' + (this.props.isContentActive() ? '-interactive' : ''); + const classname = 'pdfBox' + (this._props.isContentActive() ? '-interactive' : ''); return ( <div className={classname}> <div className="pdfBox-title-outer"> - <strong className="pdfBox-title">{StrCast(this.props.Document.title)}</strong> + <strong className="pdfBox-title">{StrCast(this.Document.title)}</strong> </div> </div> ); @@ -472,8 +473,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps key="sidebar" title="Toggle Sidebar" style={{ - display: !this.props.isContentActive() ? 'none' : undefined, - top: StrCast(this.rootDoc._layout_showTitle) === 'title' ? 20 : 5, + display: !this._props.isContentActive() ? 'none' : undefined, + top: StrCast(this.layoutDoc._layout_showTitle) === 'title' ? 20 : 5, backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK, }} onPointerDown={e => this.sidebarBtnDown(e, true)}> @@ -489,27 +490,27 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps const pdfNativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']); const nativeWidth = NumCast(this.layoutDoc.nativeWidth, pdfNativeWidth); const pdfRatio = pdfNativeWidth / nativeWidth; - return (pdfRatio * this.props.PanelWidth()) / pdfNativeWidth; + return (pdfRatio * this._props.PanelWidth()) / pdfNativeWidth; } @computed get sidebarNativeWidth() { return this.sidebarWidth() / this.pdfScale; } @computed get sidebarNativeHeight() { - return this.props.PanelHeight() / this.pdfScale; + return this._props.PanelHeight() / this.pdfScale; } sidebarNativeWidthFunc = () => this.sidebarNativeWidth; sidebarNativeHeightFunc = () => this.sidebarNativeHeight; sidebarMoveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.moveDocument(doc, targetCollection, addDocument, this.SidebarKey); sidebarRemDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, this.SidebarKey); - sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate((this.sidebarWidth() - this.props.PanelWidth()) / this.pdfScale, 0); + sidebarScreenToLocal = () => this._props.ScreenToLocalTransform().translate((this.sidebarWidth() - this._props.PanelWidth()) / this.pdfScale, 0); @computed get sidebarCollection() { const renderComponent = (tag: string) => { const ComponentTag = tag === CollectionViewType.Freeform ? CollectionFreeFormView : CollectionStackingView; return ComponentTag === CollectionStackingView ? ( <SidebarAnnos ref={this._sidebarRef} - {...this.props} - rootDoc={this.rootDoc} + {...this._props} + Document={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} setHeight={emptyFunction} @@ -521,13 +522,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps removeDocument={this.removeDocument} /> ) : ( - <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this.props.DocumentView?.()!, false), true)}> + <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this._props.DocumentView?.()!, false), true)}> <ComponentTag - {...this.props} + {...this._props} setContentView={emptyFunction} // override setContentView to do nothing NativeWidth={this.sidebarNativeWidthFunc} NativeHeight={this.sidebarNativeHeightFunc} - PanelHeight={this.props.PanelHeight} + PanelHeight={this._props.PanelHeight} PanelWidth={this.sidebarWidth} xPadding={0} yPadding={0} @@ -541,7 +542,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps moveDocument={this.sidebarMoveDocument} addDocument={this.sidebarAddDocument} ScreenToLocalTransform={this.sidebarScreenToLocal} - renderDepth={this.props.renderDepth + 1} + renderDepth={this._props.renderDepth + 1} noSidebar={true} fieldKey={this.SidebarKey} /> @@ -557,13 +558,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps @computed get renderPdfView() { TraceMobx(); const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1; - const scale = previewScale * (this.props.NativeDimScaling?.() || 1); + const scale = previewScale * (this._props.NativeDimScaling?.() || 1); return !this._pdf ? null : ( <div className="pdfBox" onContextMenu={this.specificContextMenu} style={{ - height: this.props.Document._layout_scrollTop && !this.Document._layout_fitWidth && window.screen.width > 600 ? (NumCast(this.Document._height) * this.props.PanelWidth()) / NumCast(this.Document._width) : undefined, + height: this.Document._layout_scrollTop && !this.Document._layout_fitWidth && window.screen.width > 600 ? (NumCast(this.Document._height) * this._props.PanelWidth()) / NumCast(this.Document._width) : undefined, }}> <div className="pdfBox-background" onPointerDown={e => this.sidebarBtnDown(e, false)} /> <div @@ -576,7 +577,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps top: 0, }}> <PDFViewer - {...this.props} + {...this._props} sidebarAddDoc={this.sidebarAddDocument} addDocTab={this.sidebarAddDocTab} layoutDoc={this.layoutDoc} @@ -594,7 +595,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps crop={this.crop} /> </div> - <div style={{ position: 'absolute', height: '100%', right: 0, top: 0, width: `calc(100 * ${this.sidebarWidth() / this.props.PanelWidth()}%` }}>{this.sidebarCollection}</div> + <div style={{ position: 'absolute', height: '100%', right: 0, top: 0, width: `calc(100 * ${this.sidebarWidth() / this._props.PanelWidth()}%` }}>{this.sidebarCollection}</div> {this.settingsPanel()} </div> ); @@ -604,8 +605,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps static pdfpromise = new Map<string, Promise<Pdfjs.PDFDocumentProxy>>(); render() { TraceMobx(); - const pdfView = this.renderPdfView; - + const pdfView = !this._pdf ? null : this.renderPdfView; const href = this.pdfUrl?.url.href; if (!pdfView && href) { if (PDFBox.pdfcache.get(href)) setTimeout(action(() => (this._pdf = PDFBox.pdfcache.get(href)))); |