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 | 
