From 85e290ee7a666412570f2bae43a9b62d35b425f2 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 6 Jul 2022 17:26:26 -0400
Subject: fixed pushpin behavior to work with notes in annotation sidebar.  
 fixed right-clicking on text anchors to bring up anchor menu

---
 .../views/nodes/formattedText/FormattedTextBox.tsx | 90 +++++++++++++---------
 1 file changed, 54 insertions(+), 36 deletions(-)

(limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx')

diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index f83fdffc9..27227c152 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -18,7 +18,7 @@ import { PrefetchProxy } from '../../../../fields/Proxy';
 import { RichTextField } from "../../../../fields/RichTextField";
 import { RichTextUtils } from '../../../../fields/RichTextUtils';
 import { ComputedField } from '../../../../fields/ScriptField';
-import { Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types";
+import { BoolCast, Cast, FieldValue, NumCast, ScriptCast, StrCast } from "../../../../fields/Types";
 import { GetEffectiveAcl, TraceMobx } from '../../../../fields/util';
 import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, numberRange, OmitKeys, returnZero, setupMoveUpEvents, smoothScroll, unimplementedFunction, Utils } from '../../../../Utils';
 import { GoogleApiClientUtils, Pulls, Pushes } from '../../../apis/google_docs/GoogleApiClientUtils';
@@ -617,9 +617,48 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         return false;
     }
 
+
+    @undoBatch
+    deleteAnnotation = (anchor:Doc) => {
+        LinkManager.Instance.deleteLink(DocListCast(anchor.links)[0]);
+        // const docAnnotations = DocListCast(this.props.dataDoc[this.props.fieldKey]);
+        // this.props.dataDoc[this.props.fieldKey] = new List<Doc>(docAnnotations.filter(a => a !== this.annoTextRegion));
+        // AnchorMenu.Instance.fadeOut(true);
+        this.props.select(false);
+    }
+
+    @undoBatch
+    pinToPres = (anchor:Doc) => this.props.pinToPres(anchor)
+
+    @undoBatch
+    makePushpin = (anchor:Doc) => anchor.isPushpin = !anchor.isPushpin
+
+    isPushpin = (anchor:Doc) => BoolCast(anchor.isPushpin);
+
     specificContextMenu = (e: React.MouseEvent): void => {
         const cm = ContextMenu.Instance;
 
+        const editor = this._editorView!;
+        const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY });
+        let target = (e.target as any).parentElement; // hrefs are stored on the database of the <a> node that wraps the hyerlink <span>
+        while (target && !target.dataset?.targethrefs) target = target.parentElement;
+        if (target) {
+            const hrefs = (target.dataset?.targethrefs as string)?.trim().split(" ").filter(h => h);
+            const anchorDoc = Array.from(hrefs).lastElement().replace(Doc.localServerPath(), "").split("?")[0];
+            e.persist();
+            anchorDoc && DocServer.GetRefField(anchorDoc).then(action(anchor => {
+                AnchorMenu.Instance.Status = "annotation";
+                AnchorMenu.Instance.Delete = () => this.deleteAnnotation(anchor as Doc);
+                AnchorMenu.Instance.Pinned = false;
+                AnchorMenu.Instance.PinToPres = () => this.pinToPres(anchor as Doc);
+                AnchorMenu.Instance.MakePushpin = () => this.makePushpin(anchor as Doc);
+                AnchorMenu.Instance.IsPushpin = () => this.isPushpin(anchor as Doc);
+                AnchorMenu.Instance.jumpTo(e.clientX, e.clientY, true);
+            }));
+            e.stopPropagation();
+            return;
+        }
+
         const changeItems: ContextMenuProps[] = [];
         changeItems.push({
             description: "plain", event: undoBatch(() => {
@@ -797,8 +836,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     }
 
     scrollFocus = (textAnchor: Doc, smooth: boolean) => {
+        let didToggle = false;
         if (DocListCast(this.Document[this.fieldKey + "-sidebar"]).includes(textAnchor) && !this.SidebarShown) {
             this.toggleSidebar(!smooth);
+            didToggle = true;
         }
         const textAnchorId = textAnchor[Id];
         const findAnchorFrag = (frag: Fragment, editor: EditorView) => {
@@ -851,7 +892,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             }
         }
 
-        return this._didScroll ? this._focusSpeed : undefined; // if we actually scrolled, then return some focusSpeed
+        return this._didScroll ? this._focusSpeed : didToggle ? 1: undefined; // if we actually scrolled, then return some focusSpeed
     }
 
     getScrollHeight = () => this.scrollHeight;
@@ -1251,6 +1292,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     }
 
     onPointerDown = (e: React.PointerEvent): void => {
+        if (((e.nativeEvent as any).handledByInnerReactInstance)) {
+            return e.stopPropagation();
+        } else (e.nativeEvent as any).handledByInnerReactInstance = true;
+
         if (this.Document.forceActive) e.stopPropagation();
         this.tryUpdateScrollHeight(); // if a doc a fitwidth doc is being viewed in different context (eg freeform & lightbox), then it will have conflicting heights.  so when the doc is clicked on, we want to make sure it has the appropriate height for the selected view.
         if ((e.target as any).tagName === "AUDIOTAG") {
@@ -1304,10 +1349,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         if (!this._editorView?.state.selection.empty && FormattedTextBox._canAnnotate) this.setupAnchorMenu();
         if (!this._downEvent) return;
         this._downEvent = false;
-        if ((e.nativeEvent as any).formattedHandled) {
-            console.log("handled");
-        }
-        if (!(e.nativeEvent as any).formattedHandled && this.props.isContentActive(true)) {
+        if (this.props.isContentActive(true)) {
             const editor = this._editorView!;
             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))));
@@ -1315,9 +1357,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             while (target && !target.dataset?.targethrefs) target = target.parentElement;
             FormattedTextBoxComment.update(this, editor, undefined, target?.dataset?.targethrefs, target?.dataset.linkdoc);
         }
-        (e.nativeEvent as any).formattedHandled = true;
 
-        if (e.buttons === 1 && this.props.isSelected(true) && !e.altKey) {
+        if (e.button === 0 && this.props.isSelected(true) && !e.altKey) {
             e.stopPropagation();
         }
     }
@@ -1334,8 +1375,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         }
         FormattedTextBoxComment.Hide();
 
-        (e.nativeEvent as any).formattedHandled = true;
-
         if (e.buttons === 1 && this.props.isSelected(true) && !e.altKey) {
             e.stopPropagation();
         }
@@ -1354,6 +1393,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
     @observable public static Focused: FormattedTextBox | undefined;
 
     onClick = (e: React.MouseEvent): void => {
+        if ((e.nativeEvent as any).handledByInnerReactInstance) {
+            e.stopPropagation();
+            return;
+        }
         if (Math.abs(e.clientX - this._downX) > 4 || Math.abs(e.clientY - this._downY) > 4) {
             this._forceDownNode = undefined;
             return;
@@ -1378,12 +1421,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                 this._editorView!.dispatch(this._editorView!.state.tr.setSelection(NodeSelection.create(this._editorView!.state.doc, pcords.pos)));
             }
         }
-        if ((e.nativeEvent as any).formattedHandled) {
-            e.stopPropagation();
-            return;
-        }
         if (this.props.isSelected(true)) { // if text box is selected, then it consumes all click events
-            (e.nativeEvent as any).formattedHandled = true;
+            (e.nativeEvent as any).handledByInnerReactInstance = true;
             if (this.ProseRef?.children[0] !== e.nativeEvent.target) e.stopPropagation(); // if you double click on text, then it will be selected instead of sending a double click to DocumentView & opening a lightbox.  Also,if a text box has isLinkButton, this will prevent link following if you've selected the document to edit it.
             // e.stopPropagation();  // bcz: not sure why this was here.  We need to allow the DocumentView to get clicks to process doubleClicks (see above comment)
             this.hitBulletTargets(e.clientX, e.clientY, !this._editorView?.state.selection.empty || this._forceUncollapse, false, this._forceDownNode, e.shiftKey);
@@ -1424,26 +1463,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             }
         }
     }
-    onMouseUp = (e: React.MouseEvent): void => {
-        e.stopPropagation();
-
-        const view = this._editorView as any;
-        // this interposes on prosemirror's upHandler to prevent prosemirror's up from invoked multiple times when there
-        // are nested prosemirrors.  We only want the lowest level prosemirror to be invoked.
-        if (view.mouseDown) {
-            const originalUpHandler = view.mouseDown.up;
-            view.root.removeEventListener("mouseup", originalUpHandler);
-            view.mouseDown.up = (e: MouseEvent) => {
-                if (!(e as any).formattedHandled) {
-                    originalUpHandler(e);
-                    (e as any).formattedHandled = true;
-                } else {
-                    console.log("prehandled");
-                }
-            };
-            view.root.addEventListener("mouseup", view.mouseDown.up);
-        }
-    }
     startUndoTypingBatch() {
         !this._undoTyping && (this._undoTyping = UndoManager.StartBatch("undoTyping"));
     }
@@ -1688,7 +1707,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
                     onBlur={this.onBlur}
                     onPointerUp={this.onPointerUp}
                     onPointerDown={this.onPointerDown}
-                    onMouseUp={this.onMouseUp}
                     onDoubleClick={this.onDoubleClick}
                 >
                     <div className={`formattedTextBox-outer${selected ? "-selected" : ""}`} ref={this._scrollRef}
-- 
cgit v1.2.3-70-g09d2

