diff options
Diffstat (limited to 'src/client/views/pdf/PDFViewer.tsx')
-rw-r--r-- | src/client/views/pdf/PDFViewer.tsx | 129 |
1 files changed, 59 insertions, 70 deletions
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index fa97bde3f..dd9dfa733 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -23,13 +23,12 @@ import { CollectionFreeFormView } from "../collections/collectionFreeForm/Collec import { ViewBoxAnnotatableComponent } from "../DocComponent"; import { MarqueeAnnotator } from "../MarqueeAnnotator"; import { FieldViewProps } from "../nodes/FieldView"; -import { FormattedTextBoxComment } from "../nodes/formattedText/FormattedTextBoxComment"; -import { LinkDocPreview } from "../nodes/LinkDocPreview"; import { Annotation } from "./Annotation"; import { AnchorMenu } from "./AnchorMenu"; import "./PDFViewer.scss"; const pdfjs = require('pdfjs-dist/es5/build/pdf.js'); import React = require("react"); +import { DocAfterFocusFunc } from "../nodes/DocumentView"; const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer"); const pdfjsLib = require("pdfjs-dist"); const _global = (window /* browser */ || global /* node */) as any; @@ -88,6 +87,8 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu private _coverPath: any; private _lastSearch = false; private _viewerIsSetup = false; + private _ignoreScroll = false; + private _smoothScrolling = true; @computed get allAnnotations() { return DocUtils.FilterDocs(DocListCast(this.dataDoc[this.props.fieldKey + "-annotations"]), this.props.docFilters(), this.props.docRangeFilters(), undefined); @@ -119,12 +120,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu } runInAction(() => this._showWaiting = true); this.props.startupLive && this.setupPdfJsViewer(); - if (this._mainCont.current) { - this._mainCont.current.scrollTop = this.layoutDoc._scrollTop || 0; - const observer = new _global.ResizeObserver(action((entries: any) => this._mainCont.current && (this._mainCont.current.scrollTop = this.layoutDoc._scrollTop || 0))); - observer.observe(this._mainCont.current); - this._mainCont.current.addEventListener("scroll", (e) => (e.target as any).scrollLeft = 0); - } + this._mainCont.current?.addEventListener("scroll", e => (e.target as any).scrollLeft = 0); this._disposers.searchMatch = reaction(() => Doc.IsSearchMatch(this.rootDoc), m => { @@ -141,36 +137,6 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu (SelectionManager.Views().length === 1) && this.setupPdfJsViewer(); }, { fireImmediately: true }); - this._disposers.scrollY = reaction( - () => this.Document._scrollY, - (scrollY) => { - if (scrollY !== undefined) { - (this._showCover || this._showWaiting) && this.setupPdfJsViewer(); - if (this.props.renderDepth !== -1 && !LinkDocPreview.TargetDoc && !FormattedTextBoxComment.linkDoc) { - const delay = this._mainCont.current ? 0 : 250; // wait for mainCont and try again to scroll - const durationStr = StrCast(this.Document._viewTransition).match(/([0-9]*)ms/); - const duration = durationStr ? Number(durationStr[1]) : 1000; - setTimeout(() => this._mainCont.current && smoothScroll(duration, this._mainCont.current, Math.abs(scrollY || 0)), delay); - setTimeout(() => { this.Document._scrollTop = scrollY; this.Document._scrollY = undefined; }, duration + delay); - } - } - }, - { fireImmediately: true } - ); - this._disposers.scrollPreviewY = reaction( - () => Cast(this.Document._scrollPreviewY, "number", null), - (scrollY) => { - if (scrollY !== undefined) { - (this._showCover || this._showWaiting) && this.setupPdfJsViewer(); - if (this.props.renderDepth === -1 && scrollY >= 0) { - if (!this._mainCont.current) setTimeout(() => this._mainCont.current && smoothScroll(1000, this._mainCont.current, scrollY || 0)); - else smoothScroll(1000, this._mainCont.current, scrollY || 0); - this.Document._scrollPreviewY = undefined; - } - } - }, - { fireImmediately: true } - ); this._disposers.curPage = reaction( () => this.Document._curPage, (page) => page !== undefined && page !== this._pdfViewer?.currentPageNumber && this.gotoPage(page), @@ -212,6 +178,21 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu } } + // 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, smooth: boolean, afterFocus?: DocAfterFocusFunc) => { + const mainCont = this._mainCont.current; + if (doc !== this.rootDoc && mainCont) { + const scrollTo = Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.layoutDoc._scrollTop), this.props.PanelHeight() / (this.props.scaling?.() || 1)); + if (scrollTo !== undefined) { + if (smooth) smoothScroll(500, mainCont, scrollTo); + else mainCont.scrollTop = scrollTo; + return afterFocus?.(true); + } + } + afterFocus?.(false); + } + @action setupPdfJsViewer = async () => { if (this._viewerIsSetup) return; @@ -220,14 +201,6 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu this.props.setPdfViewer(this); await this.initialLoad(); - this._disposers.scrollTop = reaction(() => Cast(this.layoutDoc._scrollTop, "number", null), - (stop) => { - if (stop !== undefined && this.layoutDoc._scrollY === undefined && this._mainCont.current) { - (this._mainCont.current.scrollTop = stop); - } - }, - { fireImmediately: true }); - this._disposers.filterScript = reaction( () => Cast(this.Document.filterScript, ScriptField), action(scriptField => { @@ -242,13 +215,40 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu this.createPdfViewer(); } - pagesinit = action(() => { + pagesinit = () => { if (this._pdfViewer._setDocumentViewerElement.offsetParent) { - this._pdfViewer.currentScaleValue = this._zoomed = 1; + runInAction(() => this._pdfViewer.currentScaleValue = this._zoomed = 1); this.gotoPage(this.Document._curPage || 1); } document.removeEventListener("pagesinit", this.pagesinit); - }); + var quickScroll: string | undefined = ""; + this._disposers.scroll = reaction( + () => NumCast(this.Document._scrollTop), + (pos) => { + if (!this._ignoreScroll) { + (this._showCover || this._showWaiting) && this.setupPdfJsViewer(); + const viewTrans = quickScroll ?? StrCast(this.Document._viewTransition); + const delay = this._mainCont.current ? 0 : 250; // wait for mainCont and try again to scroll + 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; + if (duration) { + this._smoothScrolling = true; + setTimeout(() => { + this._mainCont.current && smoothScroll(duration, this._mainCont.current, Math.abs(pos || 0)); + setTimeout(() => this._smoothScrolling = false, duration); + }, delay); + } else { + this._smoothScrolling = true; + this._mainCont.current?.scrollTo({ top: Math.abs(pos || 0) }); + this._smoothScrolling = false; + } + } + }, + { fireImmediately: true } + ); + quickScroll = undefined; + } createPdfViewer() { if (!this._mainCont.current) { // bcz: I don't think this is ever triggered or needed @@ -302,29 +302,18 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu } @action - scrollToFrame = (duration: number, top: number) => { - this._mainCont.current && smoothScroll(duration, this._mainCont.current, top); - } - - @action scrollToAnnotation = (scrollToAnnotation: Doc) => { if (scrollToAnnotation) { - const offset = (this.props.PanelHeight() / this.contentScaling) / 2; - this._mainCont.current && smoothScroll(500, this._mainCont.current, NumCast(scrollToAnnotation.y) - offset); + this.scrollFocus(scrollToAnnotation, true); Doc.linkFollowHighlight(scrollToAnnotation); } } - pageDelay: any; - @action onScroll = (e: React.UIEvent<HTMLElement>) => { - if (!LinkDocPreview.TargetDoc && !FormattedTextBoxComment.linkDoc) { - this.pageDelay && clearTimeout(this.pageDelay); - this.pageDelay = setTimeout(() => { - this.Document._scrollY === undefined && this._mainCont.current && (this.layoutDoc._scrollTop = this._mainCont.current.scrollTop); - this.pageDelay = undefined; - //this._pdfViewer && (this.Document._curPage = this._pdfViewer.currentPageNumber); - }, 1000); + if (this._mainCont.current && !this._smoothScrolling) { + this._ignoreScroll = true; + this.layoutDoc._scrollTop = this._mainCont.current.scrollTop; + this._ignoreScroll = false; } } @@ -518,8 +507,8 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu showInfo = action((anno: Opt<Doc>) => this._overlayAnnoInfo = anno); overlayTransform = () => this.scrollXf().scale(1 / this._zoomed); - panelWidth = () => (this.Document.scrollHeight || Doc.NativeHeight(this.Document) || 0); - panelHeight = () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document); + panelWidth = () => this.props.PanelWidth() / (this.props.scaling?.() || 1); // (this.Document.scrollHeight || Doc.NativeHeight(this.Document) || 0); + panelHeight = () => this.props.PanelHeight() / (this.props.scaling?.() || 1); // () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : Doc.NativeWidth(this.Document); @computed get overlayLayer() { return <div className={`pdfViewerDash-overlay${Doc.GetSelectedTool() !== InkTool.None || SnappingManager.GetIsDragging() ? "-inking" : ""}`} style={{ @@ -531,8 +520,8 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu isAnnotationOverlay={true} fieldKey={this.annotationKey} setPreviewCursor={this.setPreviewCursor} - PanelHeight={this.panelWidth} - PanelWidth={this.panelHeight} + PanelHeight={this.panelHeight} + PanelWidth={this.panelWidth} dropAction={"alias"} select={emptyFunction} active={this.annotationsActive} @@ -576,7 +565,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu {this.overlayInfo} {this.standinViews} {!this._marqueeing || !this._mainCont.current || !this._annotationLayer.current ? (null) : - <MarqueeAnnotator rootDoc={this.rootDoc} down={this._marqueeing} addDocument={this.addDocument} finishMarquee={this.finishMarquee} getPageFromScroll={this.getPageFromScroll} savedAnnotations={this._savedAnnotations} annotationLayer={this._annotationLayer.current} mainCont={this._mainCont.current} />} + <MarqueeAnnotator rootDoc={this.rootDoc} scrollTop={0} down={this._marqueeing} addDocument={this.addDocument} finishMarquee={this.finishMarquee} getPageFromScroll={this.getPageFromScroll} savedAnnotations={this._savedAnnotations} annotationLayer={this._annotationLayer.current} mainCont={this._mainCont.current} />} </div >; } }
\ No newline at end of file |