From a2ea001c425fb425e4d0cce7c59e77736da86d3d Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sat, 4 Jun 2022 20:45:29 -0400
Subject: fixed searching to highlight in text notes and to unhighlight when
 search string changes. fixed links to update when text boxes scroll (hackily)

---
 .../collectionFreeForm/CollectionFreeFormLinkView.tsx     | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index f5a5492e3..fe849ee48 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -3,7 +3,7 @@ import { observer } from "mobx-react";
 import { Doc, Field } from "../../../../fields/Doc";
 import { Id } from "../../../../fields/FieldSymbols";
 import { List } from "../../../../fields/List";
-import { NumCast } from "../../../../fields/Types";
+import { Cast, NumCast } from "../../../../fields/Types";
 import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils';
 import { LinkManager } from "../../../util/LinkManager";
 import { SelectionManager } from "../../../util/SelectionManager";
@@ -30,7 +30,14 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
     componentWillUnmount() { this._anchorDisposer?.(); }
     @action timeout = action(() => (Date.now() < this._start++ + 1000) && (this._timeout = setTimeout(this.timeout, 25)));
     componentDidMount() {
-        this._anchorDisposer = reaction(() => [this.props.A.props.ScreenToLocalTransform(), this.props.B.props.ScreenToLocalTransform()],
+        this._anchorDisposer = reaction(() => [
+            this.props.A.props.ScreenToLocalTransform(),
+            Cast(Cast(Cast(this.props.A.rootDoc, Doc, null)?.anchor1, Doc, null)?.annotationOn, Doc, null)?.scrollTop,
+            Cast(Cast(Cast(this.props.A.rootDoc, Doc, null)?.anchor1, Doc, null)?.annotationOn, Doc, null)?._highlights,
+            this.props.B.props.ScreenToLocalTransform(),
+            Cast(Cast(Cast(this.props.A.rootDoc, Doc, null)?.anchor2, Doc, null)?.annotationOn, Doc, null)?.scrollTop,
+            Cast(Cast(Cast(this.props.A.rootDoc, Doc, null)?.anchor2, Doc, null)?.annotationOn, Doc, null)?._highlights,
+        ],
             action(() => {
                 this._start = Date.now();
                 this._timeout && clearTimeout(this._timeout);
@@ -75,6 +82,8 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
             const mpy = mp[1] / A.props.PanelHeight();
             if (mpx >= 0 && mpx <= 1) linkDoc.anchor1_x = mpx * 100;
             if (mpy >= 0 && mpy <= 1) linkDoc.anchor1_y = mpy * 100;
+            if (getComputedStyle(targetAhyperlink).fontSize === "0px") linkDoc.opacity = 0;
+            else linkDoc.opacity = 1;
         }
         if (!targetBhyperlink) {
             if (linkDoc.linkAutoMove) {
@@ -253,7 +262,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
             this.props.LinkDocs[0].displayArrow = false;
         }
 
-        return !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<>
+        return !this.props.LinkDocs[0].opacity || !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<>
             <defs>
                 <marker id="arrowhead" markerWidth="4" markerHeight="3"
                     refX="0" refY="1.5" orient="auto">
-- 
cgit v1.2.3-70-g09d2


From 4bf54cdb7d2568f718446ddf6b7f17ba6a54ba91 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 5 Jun 2022 10:56:03 -0400
Subject: fixed up drawing link lines to be less jittery and smoother looking. 
 changed documentView to use a margin: auto when fitting width for something
 that can't grow to the size of the panel so that it will be centered in the
 panel and not docked at the top.

---
 src/Utils.ts                                       |  8 +--
 .../CollectionFreeFormLinkView.tsx                 | 57 +++++-----------------
 src/client/views/nodes/DocumentView.tsx            |  1 +
 src/client/views/nodes/LinkDocPreview.scss         |  6 ++-
 src/client/views/nodes/LinkDocPreview.tsx          |  7 ++-
 5 files changed, 26 insertions(+), 53 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx')

diff --git a/src/Utils.ts b/src/Utils.ts
index e6aa0ad8b..a99646731 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -219,14 +219,14 @@ export namespace Utils {
     }
 
     export function distanceBetweenHorizontalLines(xs: number, xe: number, y: number, xs2: number, xe2: number, y2: number): [number, number[]] {
-        if ((xs2 < xs && xe2 > xs) || (xs2 < xe && xe2 > xe) || (xs2 > xs && xe2 < xe)) return [Math.abs(y - y2), [Math.max(xs, xs2), y, Math.min(xe, xe2), y]];
-        if (xe2 < xs) return [Math.sqrt((xe2 - xs) * (xe2 - xs) + (y2 - y) * (y2 - y)), [xs, y, xs, y]];
+        if ((xs2 <= xs && xe2 >= xs) || (xs2 <= xe && xe2 >= xe) || (xs2 >= xs && xe2 <= xe)) return [Math.abs(y - y2), [Math.max(xs, xs2), y, Math.min(xe, xe2), y]];
+        if (xe2 <= xs) return [Math.sqrt((xe2 - xs) * (xe2 - xs) + (y2 - y) * (y2 - y)), [xs, y, xs, y]];
         //if (xs2 > xe) 
         return [Math.sqrt((xs2 - xe) * (xs2 - xe) + (y2 - y) * (y2 - y)), [xe, y, xe, y]];
     }
     export function distanceBetweenVerticalLines(x: number, ys: number, ye: number, x2: number, ys2: number, ye2: number): [number, number[]] {
-        if ((ys2 < ys && ye2 > ys) || (ys2 < ye && ye2 > ye) || (ys2 > ys && ye2 < ye)) return [Math.abs(x - x2), [x, Math.max(ys, ys2), x, Math.min(ye, ye2)]];
-        if (ye2 < ys) return [Math.sqrt((ye2 - ys) * (ye2 - ys) + (x2 - x) * (x2 - x)), [x, ys, x, ys]];
+        if ((ys2 <= ys && ye2 >= ys) || (ys2 <= ye && ye2 >= ye) || (ys2 >= ys && ye2 <= ye)) return [Math.abs(x - x2), [x, Math.max(ys, ys2), x, Math.min(ye, ye2)]];
+        if (ye2 <= ys) return [Math.sqrt((ye2 - ys) * (ye2 - ys) + (x2 - x) * (x2 - x)), [x, ys, x, ys]];
         //if (ys2 > ye) 
         return [Math.sqrt((ys2 - ye) * (ys2 - ye) + (x2 - x) * (x2 - x)), [x, ye, x, ye]];
     }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index fe849ee48..5f890c810 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -52,14 +52,10 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
         if (SnappingManager.GetIsDragging() || !A.ContentDiv || !B.ContentDiv) return;
         setTimeout(action(() => this._opacity = 0.75), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render()
         setTimeout(action(() => (!LinkDocs.length || !linkDoc.linkDisplay) && (this._opacity = 0.05)), 750); // this will unhighlight the link line.
-        const acont = A.ContentDiv.getElementsByClassName("linkAnchorBox-cont");
-        const bcont = B.ContentDiv.getElementsByClassName("linkAnchorBox-cont");
-        const adiv = acont.length ? acont[0] : A.ContentDiv;
-        const bdiv = bcont.length ? bcont[0] : B.ContentDiv;
-        const a = adiv.getBoundingClientRect();
-        const b = bdiv.getBoundingClientRect();
-        const { left: aleft, top: atop, width: awidth, height: aheight } = adiv.parentElement!.getBoundingClientRect();
-        const { left: bleft, top: btop, width: bwidth, height: bheight } = bdiv.parentElement!.getBoundingClientRect();
+        const a = A.ContentDiv.getBoundingClientRect();
+        const b = B.ContentDiv.getBoundingClientRect();
+        const { left: aleft, top: atop, width: awidth, height: aheight } = A.ContentDiv.parentElement!.getBoundingClientRect();
+        const { left: bleft, top: btop, width: bwidth, height: bheight } = B.ContentDiv.parentElement!.getBoundingClientRect();
         const apt = Utils.closestPtBetweenRectangles(aleft, atop, awidth, aheight, bleft, btop, bwidth, bheight, a.left + a.width / 2, a.top + a.height / 2);
         const bpt = Utils.closestPtBetweenRectangles(bleft, btop, bwidth, bheight, aleft, atop, awidth, aheight, apt.point.x, apt.point.y);
 
@@ -97,6 +93,8 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
             const mpy = mp[1] / B.props.PanelHeight();
             if (mpx >= 0 && mpx <= 1) linkDoc.anchor2_x = mpx * 100;
             if (mpy >= 0 && mpy <= 1) linkDoc.anchor2_y = mpy * 100;
+            if (getComputedStyle(targetBhyperlink).fontSize === "0px") linkDoc.opacity = 0;
+            else linkDoc.opacity = 1;
         }
     }
 
@@ -163,25 +161,6 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
         this.toggleProperties();
     }
 
-    // componentToHex = (c: number) => {
-    //     let hex = c.toString(16);
-    //     return hex.length == 1 ? "0" + hex : hex;
-    // }
-
-    // rgbToHex = (rgbString: string) => {
-    //     if (rgbString != "black") {
-    //         const splitString = rgbString.split(/rgb|\(|\)|,| /)
-    //         let values: number[] = []
-    //         splitString.forEach(elt => {
-    //             if (elt) {
-    //                 values.push(parseInt(elt))
-    //             }
-    //         })
-    //         return "#" + this.componentToHex(values[0]) + this.componentToHex(values[1]) + this.componentToHex(values[2]);
-    //     }
-    //     return "#000000"
-    // }
-
     @computed.struct get renderData() {
         this._start; SnappingManager.GetIsDragging();
         const { A, B, LinkDocs } = this.props;
@@ -199,32 +178,18 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
         if (!a.width || !b.width) return undefined;
         const aDocBounds = (A.props as any).DocumentView?.().getBounds() || { left: 0, right: 0, top: 0, bottom: 0 };
         const bDocBounds = (B.props as any).DocumentView?.().getBounds() || { left: 0, right: 0, top: 0, bottom: 0 };
-        const acentX = (a.left + a.right) / 2;
-        const acentY = (a.top + a.bottom) / 2;
-        const bcentX = (b.left + b.right) / 2;
-        const bcentY = (b.top + b.bottom) / 2;
-        const pt1Arc = ((acentX - aDocBounds.left) > 0.1 && (aDocBounds.right - acentX) > 0.1) ||
-            ((acentY - aDocBounds.top) > 0.1 && (aDocBounds.bottom - acentY) > 0.1);
-        const pt2Arc = ((bcentX - bDocBounds.left) > 0.1 && (bDocBounds.right - bcentX) > 0.1) ||
-            ((bcentY - bDocBounds.top) > 0.1 && (bDocBounds.bottom - bcentY) > 0.1);
-        const atop2 = this.visibleY(adiv);
-        const btop2 = this.visibleY(bdiv);
         const aleft = this.visibleX(adiv);
         const bleft = this.visibleX(bdiv);
         const clipped = aleft !== a.left || atop !== a.top || bleft !== b.left || btop !== b.top;
         const pt1 = [aleft + a.width / 2, atop + a.height / 2];
         const pt2 = [bleft + b.width / 2, btop + b.width / 2];
-        const pt1vec = [pt1[0] - (aDocBounds.left + aDocBounds.right) / 2, pt1[1] - (aDocBounds.top + aDocBounds.bottom) / 2];
-        const pt2vec = [pt2[0] - (bDocBounds.left + bDocBounds.right) / 2, pt2[1] - (bDocBounds.top + bDocBounds.bottom) / 2];
+        const pt1vec = [(bDocBounds.left + bDocBounds.right) / 2 - pt1[0], (bDocBounds.top + bDocBounds.bottom) / 2 - pt1[1]];
+        const pt2vec = [(aDocBounds.left + aDocBounds.right) / 2 - pt2[0], (aDocBounds.top + aDocBounds.bottom) / 2 - pt2[1]];
         const pt1len = Math.sqrt((pt1vec[0] * pt1vec[0]) + (pt1vec[1] * pt1vec[1]));
         const pt2len = Math.sqrt((pt2vec[0] * pt2vec[0]) + (pt2vec[1] * pt2vec[1]));
         const ptlen = Math.sqrt((pt1[0] - pt2[0]) * (pt1[0] - pt2[0]) + (pt1[1] - pt2[1]) * (pt1[1] - pt2[1])) / 2;
-        const pt1norm = clipped ? [0, 0] : !pt1Arc ? [pt1vec[0] / pt1len * ptlen, pt1vec[1] / pt1len * ptlen] :
-            Math.abs(acentY - aDocBounds.top) < 0.01 ||
-                Math.abs(acentY - aDocBounds.bottom) < 0.01 ? [0, (pt2[1] - pt1[1]) / 2] : [(pt2[0] - pt1[0]) / 2, 0];
-        const pt2norm = clipped ? [0, 0] : !pt2Arc ? [pt2vec[0] / pt2len * ptlen, pt2vec[1] / pt2len * ptlen] :
-            Math.abs(bcentY - bDocBounds.top) < 0.01 ||
-                Math.abs(bcentY - bDocBounds.bottom) < 0.01 ? [0, (pt1[1] - pt2[1]) / 2] : [(pt1[0] - pt2[0]) / 2, 0];
+        const pt1norm = clipped ? [0, 0] : [pt1vec[0] / pt1len * ptlen, pt1vec[1] / pt1len * ptlen];
+        const pt2norm = clipped ? [0, 0] : [pt2vec[0] / pt2len * ptlen, pt2vec[1] / pt2len * ptlen];
         const pt1normlen = Math.sqrt(pt1norm[0] * pt1norm[0] + pt1norm[1] * pt1norm[1]) || 1;
         const pt2normlen = Math.sqrt(pt2norm[0] * pt2norm[0] + pt2norm[1] * pt2norm[1]) || 1;
         const pt1normalized = [pt1norm[0] / pt1normlen, pt1norm[1] / pt1normlen];
@@ -262,7 +227,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
             this.props.LinkDocs[0].displayArrow = false;
         }
 
-        return !this.props.LinkDocs[0].opacity || !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<>
+        return this.props.LinkDocs[0].opacity === 0 || !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<>
             <defs>
                 <marker id="arrowhead" markerWidth="4" markerHeight="3"
                     refX="0" refY="1.5" orient="auto">
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 6e4d6a52e..e23bf24a9 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1341,6 +1341,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
                         transition: this.props.dataTransition,
                         position: this.props.Document.isInkMask ? "absolute" : undefined,
                         transform: isButton ? undefined : `translate(${this.centeringX}px, ${this.centeringY}px)`,
+                        margin: this.fitWidth && this.panelHeight >= (this.ComponentView?.getScrollHeight?.() ?? 0) ? "auto" : undefined,
                         width: isButton || isPresTreeElement ? "100%" : xshift() ?? `${100 * (this.props.PanelWidth() - this.Xshift * 2) / this.props.PanelWidth()}%`,
                         height: isButton || this.props.forceAutoHeight ? undefined : yshift() ?? (this.fitWidth ? `${this.panelHeight}px` :
                             `${100 * this.effectiveNativeHeight / this.effectiveNativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%`),
diff --git a/src/client/views/nodes/LinkDocPreview.scss b/src/client/views/nodes/LinkDocPreview.scss
index 06ae466f0..3febbcecb 100644
--- a/src/client/views/nodes/LinkDocPreview.scss
+++ b/src/client/views/nodes/LinkDocPreview.scss
@@ -1,4 +1,4 @@
- .linkDocPreview {
+.linkDocPreview {
     position: absolute;
     pointer-events: all;
     background-color: lightblue;
@@ -8,11 +8,14 @@
     border-bottom: 8px solid white;
     border-right: 8px solid white;
     z-index: 2004;
+
     .linkDocPreview-inner {
         background-color: white;
         width: 100%;
         height: 100%;
         pointer-events: none;
+        display: flex;
+        flex-direction: column;
 
         .linkDocPreview-info {
             height: 37px;
@@ -21,6 +24,7 @@
             .linkDocPreview-buttonBar {
                 float: right;
             }
+
             .linkDocPreview-title {
                 padding-right: 4px;
                 float: left;
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index b6a9cd49b..152288d8b 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -108,8 +108,11 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
     }
     nextHref = (e: React.PointerEvent) => {
         setupMoveUpEvents(this, e, returnFalse, emptyFunction, action(() => {
-            this._linkDoc = undefined;
-            this._hrefInd = (this._hrefInd + 1) % (this.props.hrefs?.length || 1);
+            const nextHrefInd = (this._hrefInd + 1) % (this.props.hrefs?.length || 1);
+            if (nextHrefInd !== this._hrefInd) {
+                this._linkDoc = undefined;
+                this._hrefInd = nextHrefInd;
+            }
         }), true);
     }
 
-- 
cgit v1.2.3-70-g09d2

