From f8008ec8d21f48591ba54a934022278c63852dba Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 11 Feb 2021 17:07:07 -0500 Subject: now pdf/web/text scroll to the target and then pan the document to be in view. --- src/client/views/pdf/PDFViewer.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index dd9dfa733..0429b61dc 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -180,17 +180,23 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { + scrollFocus = (doc: Doc, smooth: boolean, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc) => { const mainCont = this._mainCont.current; + let focusSpeed = 0; + let endFocus = afterFocus; 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); + focusSpeed = 500; + + if (smooth) smoothScroll(focusSpeed, mainCont, scrollTo); else mainCont.scrollTop = scrollTo; - return afterFocus?.(true); + + endFocus = async (moved: boolean) => afterFocus ? await afterFocus(true) : false; } } - afterFocus?.(false); + (this.props as any).DocumentView().props.focus(this.rootDoc, willZoom, scale, (didFocus: boolean) => + new Promise(res => setTimeout(async () => res(endFocus ? await endFocus(didFocus) : false), focusSpeed))); } @action -- cgit v1.2.3-70-g09d2 From 7dbd1417fe12b54cdab44fd25adb6c5a9c52bac9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 11 Feb 2021 18:11:57 -0500 Subject: more focus refactoring and some bug fixes - resetting target document when recursively focusing. --- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 12 ++++++------ src/client/views/nodes/LinkDocPreview.tsx | 1 + src/client/views/nodes/WebBox.tsx | 10 ++++------ .../views/nodes/formattedText/FormattedTextBox.tsx | 20 +++++++++----------- src/client/views/pdf/PDFViewer.tsx | 10 +++------- 6 files changed, 24 insertions(+), 31 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 8835782f9..c18ef7a3b 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -951,7 +951,7 @@ export class CollectionFreeFormView extends CollectionSubView - new Promise(res => setTimeout(async () => res(await endFocus(didMove || didFocus)), focusSpeed)), xf.transform(docTransform ?? Transform.Identity())); + new Promise(res => setTimeout(async () => res(await endFocus(didMove || didFocus)), focusSpeed)), xf); } } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 82bcc3993..40dfd1643 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -47,7 +47,7 @@ export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterF export type StyleProviderFunc = (doc: Opt, props: Opt, property: string) => any; export interface DocComponentView { getAnchor: () => Doc; - scrollFocus?: (doc: Doc, smooth: boolean, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc) => void; + scrollFocus?: (doc: Doc, smooth: boolean) => Opt; // returns the duration of the focus back?: () => boolean; forward?: () => boolean; url?: () => string; @@ -376,11 +376,11 @@ export class DocumentViewInternal extends DocComponent { - if (this._componentView?.scrollFocus) { - this._componentView?.scrollFocus?.(doc, !LinkDocPreview.LinkInfo, willZoom, scale, afterFocus); // bcz: smooth parameter should really be passed into focus() instead of inferred here - } else { - this.props.focus(doc, willZoom, scale, afterFocus, docTransform); - } + const focusSpeed = this._componentView?.scrollFocus?.(doc, !LinkDocPreview.LinkInfo); // bcz: smooth parameter should really be passed into focus() instead of inferred here + const endFocus = focusSpeed === undefined ? afterFocus : async (moved: boolean) => afterFocus ? await afterFocus(true) : false; + this.props.focus(docTransform ? doc : this.rootDoc, willZoom, scale, (didFocus: boolean) => + new Promise(res => setTimeout(async () => res(endFocus ? await endFocus(didFocus) : false), focusSpeed ?? 0)), docTransform); + } onClick = action((e: React.MouseEvent | React.PointerEvent) => { if (!e.nativeEvent.cancelBubble && !this.Document.ignoreClick && this.props.renderDepth >= 0 && diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 6155ed493..150a549cb 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -99,6 +99,7 @@ export class LinkDocPreview extends React.Component { followLink = (e: React.PointerEvent) => { if (this._linkDoc && this._linkSrc) { + LinkDocPreview.Clear(); LinkManager.FollowLink(this._linkDoc, this._linkSrc, this.props.docProps, false); } else if (this.props.hrefs?.length) { this.props.docProps?.addDocTab(Docs.Create.WebDocument(this.props.hrefs[0], { title: this.props.hrefs[0], _width: 200, _height: 400, useCors: true }), "add:right"); diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 4dbf78e35..662477c05 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -111,9 +111,8 @@ export class WebBox extends ViewBoxAnnotatableComponent this.rootDoc; - scrollFocus = (doc: Doc, smooth: boolean, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc) => { - let focusSpeed = 0; - let endFocus = afterFocus; + scrollFocus = (doc: Doc, smooth: boolean) => { + let focusSpeed: Opt; if (doc !== this.rootDoc && this.webpage && this._outerRef.current) { const scrollTo = Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.layoutDoc._scrollTop), this.props.PanelHeight() / (this.props.scaling?.() || 1)); if (scrollTo !== undefined) { @@ -122,13 +121,12 @@ export class WebBox extends ViewBoxAnnotatableComponent afterFocus ? await afterFocus(true) : false; } } else { this._initialScroll = NumCast(doc.y); } - (this.props as any).DocumentView().props.focus(this.rootDoc, willZoom, scale, (didFocus: boolean) => - new Promise(res => setTimeout(async () => res(endFocus ? await endFocus(didFocus) : false), focusSpeed))); + + return focusSpeed; } async componentDidMount() { diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 60eae2a55..646d98347 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -868,7 +868,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp return this.active();//this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0; } - scrollFocus = (doc: Doc, smooth: boolean, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc) => { + focusSpeed: Opt; + scrollFocus = (doc: Doc, smooth: boolean) => { const anchorId = doc[Id]; const findAnchorFrag = (frag: Fragment, editor: EditorView) => { const nodes: Node[] = []; @@ -894,14 +895,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp }; let start = 0; - let focusSpeed = 0; - let endFocus = afterFocus; if (this._editorView && anchorId) { - focusSpeed = 1500; const editor = this._editorView; const ret = findAnchorFrag(editor.state.doc.content, editor); if (ret.frag.size > 2 && ret.start >= 0) { + smooth && (this.focusSpeed = 500); let selection = TextSelection.near(editor.state.doc.resolve(ret.start)); // default to near the start if (ret.frag.firstChild) { selection = TextSelection.between(editor.state.doc.resolve(ret.start), editor.state.doc.resolve(ret.start + ret.frag.firstChild.nodeSize)); // bcz: looks better to not have the target selected @@ -911,13 +910,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp addStyleSheetRule(FormattedTextBox._highlightStyleSheet, `${escAnchorId}`, { background: "yellow" }); setTimeout(() => { clearStyleSheetRules(FormattedTextBox._highlightStyleSheet); - afterFocus?.(true); - }, focusSpeed); - endFocus = async (moved: boolean) => afterFocus ? await afterFocus(true) : false; + this.focusSpeed = undefined; + }, this.focusSpeed); } } - (this.props as any).DocumentView().props.focus(this.rootDoc, willZoom, scale, (didFocus: boolean) => - new Promise(res => setTimeout(async () => res(endFocus ? await endFocus(didFocus) : false), focusSpeed))); + + return this.focusSpeed; } componentDidMount() { @@ -1228,8 +1226,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const scrollRef = self._scrollRef.current; if ((docPos.top < viewRect.top || docPos.top > viewRect.bottom) && scrollRef) { const scrollPos = scrollRef.scrollTop + (docPos.top - viewRect.top) * self.props.ScreenToLocalTransform().Scale; - if (!LinkDocPreview.LinkInfo) { - scrollPos && smoothScroll(500, scrollRef, scrollPos); + if (this.focusSpeed !== undefined) { + scrollPos && smoothScroll(this.focusSpeed, scrollRef, scrollPos); } else { scrollRef.scrollTo({ top: scrollPos }); } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 0429b61dc..c1ec7fcbb 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -180,10 +180,9 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { + scrollFocus = (doc: Doc, smooth: boolean) => { const mainCont = this._mainCont.current; - let focusSpeed = 0; - let endFocus = afterFocus; + let focusSpeed: Opt; 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) { @@ -191,12 +190,9 @@ export class PDFViewer extends ViewBoxAnnotatableComponent afterFocus ? await afterFocus(true) : false; } } - (this.props as any).DocumentView().props.focus(this.rootDoc, willZoom, scale, (didFocus: boolean) => - new Promise(res => setTimeout(async () => res(endFocus ? await endFocus(didFocus) : false), focusSpeed))); + return focusSpeed; } @action -- cgit v1.2.3-70-g09d2 From d30f5b4855a0ad500cc5784260128ecc269f6450 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 12 Feb 2021 13:33:36 -0500 Subject: streamlined double-clicking to always open lightbox no matter what document you click on (except webbox's in native selection mode). shift -double-click re-centers a freeform view. --- .../collectionFreeForm/CollectionFreeFormView.tsx | 6 ++-- src/client/views/nodes/DocumentView.tsx | 41 +++++++++++----------- .../views/nodes/formattedText/FormattedTextBox.tsx | 20 +++++++---- .../formattedText/FormattedTextBoxComment.tsx | 7 ++-- src/client/views/pdf/PDFViewer.tsx | 13 ++++--- 5 files changed, 49 insertions(+), 38 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 1a6c6bf0c..7aecf12b0 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -608,13 +608,13 @@ export class CollectionFreeFormView extends CollectionSubView { if (this.layoutDoc.targetScale && (Math.abs(e.pageX - this._downX) < 3 && Math.abs(e.pageY - this._downY) < 3)) { - if (Date.now() - this._lastTap < 300) { // reset zoom of freeform view to 1-to-1 on a double click + if (Date.now() - this._lastTap < 300) { // reset zoom of freeform view to 1-to-1 on a double click if (e.shiftKey) { - LightboxView.SetLightboxDoc(this.rootDoc, this.childDocs); - } else { this.scaleAtPt(this.getTransform().transformPoint(e.clientX, e.clientY), 1); e.stopPropagation(); e.preventDefault(); + } else { + LightboxView.SetLightboxDoc(this.rootDoc, this.childDocs); } } this._lastTap = Date.now(); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 66436fa75..bcf12c93c 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -393,26 +393,24 @@ export class DocumentViewInternal extends DocComponent this.onDoubleClickHandler.script.run({ - this: this.layoutDoc, - self: this.rootDoc, - scriptContext: this.props.scriptContext, - thisContainer: this.props.ContainingCollectionDoc, - documentView: this.props.DocumentView(), - clientX: e.clientX, - clientY: e.clientY, - shiftKey: e.shiftKey - }, console.log); - UndoManager.RunInBatch(() => func().result?.select === true ? this.props.select(false) : "", "on double click"); - } else if (!Doc.IsSystem(this.props.Document)) { - if (this.props.Document.type !== DocumentType.LABEL) { - UndoManager.RunInBatch(() => this.props.addDocTab((this.rootDoc._fullScreenView as Doc) || this.rootDoc, "lightbox"), "double tap"); - SelectionManager.DeselectAll(); - } - Doc.UnBrushDoc(this.props.Document); + if (this.onDoubleClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself + const func = () => this.onDoubleClickHandler.script.run({ + this: this.layoutDoc, + self: this.rootDoc, + scriptContext: this.props.scriptContext, + thisContainer: this.props.ContainingCollectionDoc, + documentView: this.props.DocumentView(), + clientX: e.clientX, + clientY: e.clientY, + shiftKey: e.shiftKey + }, console.log); + UndoManager.RunInBatch(() => func().result?.select === true ? this.props.select(false) : "", "on double click"); + } else if (!Doc.IsSystem(this.props.Document)) { + if (this.props.Document.type !== DocumentType.LABEL) { + UndoManager.RunInBatch(() => this.props.addDocTab((this.rootDoc._fullScreenView as Doc) || this.rootDoc, "lightbox"), "double tap"); + SelectionManager.DeselectAll(); } + Doc.UnBrushDoc(this.props.Document); } } else if (this.onClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself const shiftKey = e.shiftKey; @@ -475,7 +473,8 @@ export class DocumentViewInternal extends DocComponent { return json?.indexOf("\"storedMarks\"") === -1 ? json?.replace(/"selection":.*/, "") : json?.replace(/"selection":"\"storedMarks\""/, "\"storedMarks\""); }; @@ -1337,24 +1335,34 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp FormattedTextBoxComment.textBox = this; if (e.button === 0 && (this.props.rootSelected(true) || this.props.isSelected(true)) && !e.altKey && !e.ctrlKey && !e.metaKey) { if (e.clientX < this.ProseRef!.getBoundingClientRect().right) { // stop propagation if not in sidebar - e.stopPropagation(); // if the text box is selected, then it consumes all down events + // bcz: Change. drag selecting requires that preventDefault is NOT called. This used to happen in DocumentView, + // but that's changed, so this shouldn't be needed. + //e.stopPropagation(); // if the text box is selected, then it consumes all down events + document.addEventListener("pointerup", this.onSelectEnd); + document.addEventListener("pointermove", this.onSelectMove); } } if (e.button === 2 || (e.button === 0 && e.ctrlKey)) { e.preventDefault(); } } + onSelectMove = (e: PointerEvent) => e.stopPropagation(); + onSelectEnd = (e: PointerEvent) => { + document.removeEventListener("pointerup", this.onSelectEnd); + document.removeEventListener("pointermove", this.onSelectMove); + } onPointerUp = (e: React.PointerEvent): void => { + FormattedTextBox.CanAnnotate = true; + if (!this._editorView?.state.selection.empty && FormattedTextBox.CanAnnotate) this.setupAnchorMenu(); if (!this._downEvent) return; this._downEvent = false; if (!(e.nativeEvent as any).formattedHandled && this.active(true)) { const editor = this._editorView!; - FormattedTextBoxComment.textBox = this; const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY }); !this.props.isSelected(true) && editor.dispatch(editor.state.tr.setSelection(new TextSelection(editor.state.doc.resolve(pcords?.pos || 0)))); const target = (e.target as any).parentElement; // hrefs are store don the database of the node that wraps the hyerlink - FormattedTextBoxComment.update(editor, undefined, target?.dataset?.targethrefs); + FormattedTextBoxComment.update(this, editor, undefined, target?.dataset?.targethrefs); } (e.nativeEvent as any).formattedHandled = true; @@ -1451,7 +1459,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp (e.nativeEvent as any).formattedHandled = true; if (this.props.isSelected(true)) { // if text box is selected, then it consumes all click events - e.stopPropagation(); + // e.stopPropagation(); // bcz: not sure why this was here. We need to allow the DocumentView to get clicks to process doubleClicks this.hitBulletTargets(e.clientX, e.clientY, !this._editorView?.state.selection.empty || this._forceUncollapse, false, this._forceDownNode, e.shiftKey); } this._forceUncollapse = !(this._editorView!.root as any).getSelection().isCollapsed; diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index 89df5e246..900b702c6 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -82,9 +82,10 @@ export class FormattedTextBoxComment { FormattedTextBoxComment.tooltip.style.display = ""; } - static update(view: EditorView, lastState?: EditorState, hrefs: string = "") { - if (FormattedTextBoxComment.textBox && (hrefs || !lastState?.doc.eq(view.state.doc) || !lastState?.selection.eq(view.state.selection))) { - FormattedTextBoxComment.setupPreview(view, FormattedTextBoxComment.textBox, hrefs ? hrefs.trim().split(" ") : undefined); + static update(textBox: FormattedTextBox, view: EditorView, lastState?: EditorState, hrefs: string = "") { + FormattedTextBoxComment.textBox = textBox; + if ((hrefs || !lastState?.doc.eq(view.state.doc) || !lastState?.selection.eq(view.state.selection))) { + FormattedTextBoxComment.setupPreview(view, textBox, hrefs ? hrefs.trim().split(" ") : undefined); } } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index c1ec7fcbb..0ba08685a 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -363,9 +363,11 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { const hit = document.elementFromPoint(e.clientX, e.clientY); - if (hit && hit.localName === "span" && this.annotationsActive(true)) { // drag selecting text stops propagation - e.button === 0 && e.stopPropagation(); - } + // bcz: Change. drag selecting requires that preventDefault is NOT called. This used to happen in DocumentView, + // but that's changed, so this shouldn't be needed. + // if (hit && hit.localName === "span" && this.annotationsActive(true)) { // drag selecting text stops propagation + // e.button === 0 && e.stopPropagation(); + // } // if alt+left click, drag and annotate this._downX = e.clientX; this._downY = e.clientY; @@ -376,6 +378,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent void) => this._setPreviewCursor = func; -- cgit v1.2.3-70-g09d2 From ffeada4e258e1786536b579b17798932bf4b8a8a Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 12 Feb 2021 14:53:37 -0500 Subject: fixed bejhavior of Annotations when clicked to use FollowLink so that behavior is consistent. previously in a lightbox links within a pdf woud unnecessarily open the the PDF in its context --- src/client/views/LightboxView.tsx | 10 ++++++++-- src/client/views/nodes/WebBox.tsx | 2 +- src/client/views/pdf/Annotation.tsx | 31 +++++++------------------------ src/client/views/pdf/PDFViewer.tsx | 3 +-- 4 files changed, 17 insertions(+), 29 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 529eecacf..4c6592e58 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -11,6 +11,8 @@ import { DocumentView } from './nodes/DocumentView'; import { DefaultStyleProvider } from './StyleProvider'; import { DocUtils } from '../documents/Documents'; import { DocumentManager } from '../util/DocumentManager'; +import { SelectionManager } from '../util/SelectionManager'; +import { TabDocView } from './collections/TabDocView'; interface LightboxViewProps { PanelWidth: number; @@ -51,6 +53,10 @@ export class LightboxView extends React.Component { ; } + addDocTab = (doc: Doc, location: string) => { + SelectionManager.DeselectAll(); + return LightboxView.SetLightboxDoc(doc); + } render() { if (LightboxView.LightboxHistory.lastElement() !== LightboxView.LightboxDoc) LightboxView.LightboxHistory.push(LightboxView.LightboxDoc); @@ -73,8 +79,8 @@ export class LightboxView extends React.Component { Document={LightboxView.LightboxDoc} DataDoc={undefined} addDocument={undefined} - addDocTab={returnFalse} - pinToPres={emptyFunction} + addDocTab={this.addDocTab} + pinToPres={TabDocView.PinDoc} rootSelected={returnTrue} docViewPath={returnEmptyDoclist} removeDocument={undefined} diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 662477c05..abda0ed3a 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -425,7 +425,7 @@ export class WebBox extends ViewBoxAnnotatableComponent {this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno => - ) + ) } ; } diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index cd32c2c3a..4e3721e2b 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -9,42 +9,30 @@ import { LinkManager } from "../../util/LinkManager"; import { undoBatch } from "../../util/UndoManager"; import "./Annotation.scss"; import { AnchorMenu } from "./AnchorMenu"; +import { FieldViewProps, FieldView } from "../nodes/FieldView"; -interface IAnnotationProps { +interface IAnnotationProps extends FieldViewProps { anno: Doc; - addDocTab: (document: Doc, where: string) => boolean; - pinToPres: (document: Doc, unpin?: boolean) => void; - focus: (doc: Doc) => void; - select: (isCtrlPressed: boolean) => void; dataDoc: Doc; fieldKey: string; showInfo: (anno: Opt) => void; } - @observer export class Annotation extends React.Component { render() { return DocListCast(this.props.anno.annotations).map(a => - ); + ); } } -interface IRegionAnnotationProps { - anno: Doc; +interface IRegionAnnotationProps extends IAnnotationProps { x: number; y: number; width: number; height: number; - addDocTab: (document: Doc, where: string) => boolean; - pinToPres: (document: Doc, unpin: boolean) => void; - select: (isCtrlPressed: boolean) => void; document: Doc; - dataDoc: Doc; - fieldKey: string; - showInfo: (anno: Opt) => void; } - @observer class RegionAnnotation extends React.Component { private _reactionDisposer?: IReactionDisposer; @@ -90,8 +78,7 @@ class RegionAnnotation extends React.Component { @undoBatch pinToPres = () => { const group = FieldValue(Cast(this.props.document.group, Doc)); - const isPinned = group && Doc.isDocPinned(group) ? true : false; - group && this.props.pinToPres(group, isPinned); + group && this.props.pinToPres(group); } @undoBatch @@ -115,13 +102,9 @@ class RegionAnnotation extends React.Component { AnchorMenu.Instance.jumpTo(e.clientX, e.clientY, true); e.stopPropagation(); } - else if (e.button === 0) { - e.persist(); + else if (e.button === 0 && this.props.document.group instanceof Doc) { e.stopPropagation(); - PromiseValue(this.props.document.group).then(annoGroup => annoGroup instanceof Doc && - LinkManager.traverseLink(undefined, annoGroup, (doc, followLinkLocation) => this.props.addDocTab(doc, e.ctrlKey ? "add" : followLinkLocation), false, undefined, - () => this.props.select(false)) - ); + LinkManager.FollowLink(undefined, this.props.document.group, this.props, false); } } diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 0ba08685a..17936847e 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -28,7 +28,6 @@ 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; @@ -496,7 +495,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent {this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno => - ) + ) } ; } -- cgit v1.2.3-70-g09d2 From 926665e2367ff6a201a48618df6f7985ddbcb4b0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 12 Feb 2021 16:45:06 -0500 Subject: fixed previewing/scrollingto targets in web boxes and PDFs. fixed following link to textanchor when rtf doc is not displayed. --- src/client/util/DocumentManager.ts | 20 +++++++++----------- src/client/views/nodes/LinkDocPreview.tsx | 4 ++-- src/client/views/nodes/PDFBox.tsx | 14 ++++++++++++-- src/client/views/nodes/WebBox.tsx | 5 ++++- src/client/views/pdf/PDFViewer.tsx | 18 ++++++++++++++---- 5 files changed, 41 insertions(+), 20 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 5b4917a30..d2251583c 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -141,7 +141,7 @@ export class DocumentManager { finished?: () => void, ): Promise => { const getFirstDocView = LightboxView.LightboxDoc ? DocumentManager.Instance.getLightboxDocumentView : DocumentManager.Instance.getFirstDocumentView; - const docView = getFirstDocView(targetDoc, originatingDoc); + let docView = getFirstDocView(targetDoc, originatingDoc); const highlight = () => { const finalDocView = getFirstDocView(targetDoc); finalDocView && Doc.linkFollowHighlight(finalDocView.rootDoc); @@ -159,19 +159,17 @@ export class DocumentManager { finished?.(); return false; }; - let annotatedDoc = Cast(targetDoc.annotationOn, Doc, null); + const annotatedDoc = Cast(targetDoc.annotationOn, Doc, null); + const rtfView = annotatedDoc && getFirstDocView(annotatedDoc); const contextDocs = docContext ? await DocListCastAsync(docContext.data) : undefined; const contextDoc = contextDocs?.find(doc => Doc.AreProtosEqual(doc, targetDoc) || Doc.AreProtosEqual(doc, annotatedDoc)) ? docContext : undefined; const targetDocContext = contextDoc || annotatedDoc; const targetDocContextView = targetDocContext && getFirstDocView(targetDocContext); - if (!docView && annotatedDoc && annotatedDoc !== originatingDoc?.context && targetDoc.type === DocumentType.TEXTANCHOR) { - const first = getFirstDocView(annotatedDoc); - if (first) { - annotatedDoc = first.rootDoc; - first.focus(targetDoc, false); - } - } else if (docView && (targetDocContextView || !targetDocContext)) { // we have a docView already and aren't forced to create a new one ... just focus on the document. TODO move into view if necessary otherwise just highlight? - docView.props.focus(docView.rootDoc, willZoom, undefined, (didFocus: boolean) => + if (!docView && targetDoc.type === DocumentType.TEXTANCHOR && rtfView) { + rtfView.focus(targetDoc, false); + } + else if (docView) { + docView.props.focus(targetDoc, willZoom, undefined, (didFocus: boolean) => new Promise(res => { focusAndFinish(didFocus); res(); @@ -205,7 +203,7 @@ export class DocumentManager { // we didn't find the target, so it must have moved out of the context. Go back to just creating it. if (closeContextIfNotFound) targetDocContextView.props.removeDocument?.(targetDocContextView.rootDoc); if (targetDoc.layout) { // there will no layout for a TEXTANCHOR type document - Doc.SetInPlace(targetDoc, "annotationOn", undefined, false); + // Doc.SetInPlace(targetDoc, "annotationOn", undefined, false); createViewFunc(Doc.BrushDoc(targetDoc), finished); // create a new view of the target } } else { diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx index 488ce493c..7bd5d14d2 100644 --- a/src/client/views/nodes/LinkDocPreview.tsx +++ b/src/client/views/nodes/LinkDocPreview.tsx @@ -3,7 +3,7 @@ import { Tooltip } from '@material-ui/core'; import { action, computed, observable } from 'mobx'; import { observer } from "mobx-react"; import wiki from "wikijs"; -import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; +import { Doc, DocListCast, HeightSym, Opt, WidthSym, DocCastAsync } from "../../../fields/Doc"; import { NumCast, StrCast } from "../../../fields/Types"; import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, setupMoveUpEvents, Utils } from "../../../Utils"; import { DocServer } from '../../DocServer'; @@ -45,7 +45,7 @@ export class LinkDocPreview extends React.Component { if (anchor1 && anchor2) { linkTarget = Doc.AreProtosEqual(anchor1, this._linkSrc) || Doc.AreProtosEqual(anchor1?.annotationOn as Doc, this._linkSrc) ? anchor2 : anchor1; } - this._targetDoc = linkTarget?.annotationOn as Doc ?? linkTarget; + linkTarget && DocCastAsync(linkTarget.annotationOn).then(action(anno => this._targetDoc = anno)); this._toolTipText = ""; } componentDidUpdate(props: any) { diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index c20d958ff..b941c07f6 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -80,7 +80,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent this._pdfViewer?.scrollFocus(doc, smooth); + initialScrollTarget: Opt; + scrollFocus = (doc: Doc, smooth: boolean) => { + this.initialScrollTarget = doc; + return this._pdfViewer?.scrollFocus(doc, smooth); + } getAnchor = () => this.rootDoc; componentWillUnmount() { this._selectReactionDisposer?.(); } componentDidMount() { @@ -128,7 +132,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent this.props.whenActiveChanged(this._isChildActive = isActive)); - setPdfViewer = (pdfViewer: PDFViewer) => { this._pdfViewer = pdfViewer; }; + setPdfViewer = (pdfViewer: PDFViewer) => { + this._pdfViewer = pdfViewer; + if (this.initialScrollTarget) { + this.scrollFocus(this.initialScrollTarget, false); + this.initialScrollTarget = undefined; + } + }; searchStringChanged = (e: React.ChangeEvent) => this._searchString = e.currentTarget.value; settingsPanel() { diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index abda0ed3a..663a8b8e4 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -30,6 +30,7 @@ import { DocAfterFocusFunc } from "./DocumentView"; import { FieldView, FieldViewProps } from './FieldView'; import "./WebBox.scss"; import React = require("react"); +import { LinkDocPreview } from "./LinkDocPreview"; const htmlToText = require("html-to-text"); type WebDocument = makeInterface<[typeof documentSchema]>; @@ -119,7 +120,9 @@ export class WebBox extends ViewBoxAnnotatableComponent; private _smoothScrolling = true; @computed get allAnnotations() { @@ -182,14 +184,16 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { const mainCont = this._mainCont.current; let focusSpeed: Opt; - if (doc !== this.rootDoc && mainCont) { + if (doc !== this.rootDoc && mainCont && this._pdfViewer) { const scrollTo = Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.layoutDoc._scrollTop), this.props.PanelHeight() / (this.props.scaling?.() || 1)); if (scrollTo !== undefined) { focusSpeed = 500; if (smooth) smoothScroll(focusSpeed, mainCont, scrollTo); - else mainCont.scrollTop = scrollTo; + else this._mainCont.current?.scrollTo({ top: Math.abs(scrollTo || 0) }); } + } else { + this._initialScroll = NumCast(doc.y); } return focusSpeed; } @@ -222,7 +226,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent NumCast(this.Document._scrollTop), (pos) => { @@ -249,6 +253,10 @@ export class PDFViewer extends ViewBoxAnnotatableComponent) => { if (this._mainCont.current && !this._smoothScrolling) { this._ignoreScroll = true; - this.layoutDoc._scrollTop = this._mainCont.current.scrollTop; + if (!LinkDocPreview.LinkInfo) { + this.layoutDoc._scrollTop = this._mainCont.current.scrollTop; + } this._ignoreScroll = false; } } -- cgit v1.2.3-70-g09d2