From 43496b4cd19a06d2682f2416a4273e25cdcb55a0 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 7 Oct 2021 08:47:22 -0400
Subject: Revert "Revert "Merge pull request #34 from brown-dash/linking-anh""

This reverts commit 4e6a1d7a37c8c28014a9f7cd0d92f17c8f29454d.
---
 .../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 f6c2707da..88cd0feb3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -42,7 +42,7 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
         const { A, B, LinkDocs } = this.props;
         const linkDoc = LinkDocs[0];
         if (SnappingManager.GetIsDragging() || !A.ContentDiv || !B.ContentDiv) return;
-        setTimeout(action(() => this._opacity = 1), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render()
+        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");
@@ -180,15 +180,24 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
 
     render() {
         if (!this.renderData) return (null);
+
         const { a, b, pt1norm, pt2norm, aActive, bActive, textX, textY, pt1, pt2 } = this.renderData;
         LinkManager.currentLink = this.props.LinkDocs[0];
         const linkRelationship = Field.toString(LinkManager.currentLink?.linkRelationship as any as Field); //get string representing relationship
         const linkRelationshipList = Doc.UserDoc().linkRelationshipList as List<string>;
         const linkColorList = Doc.UserDoc().linkColorList as List<string>;
+        const linkRelationshipSizes = Doc.UserDoc().linkRelationshipSizes as List<number>;
+        const currRelationshipIndex = linkRelationshipList.indexOf(linkRelationship);
+
         //access stroke color using index of the relationship in the color list (default black)
-        const strokeColor = linkRelationshipList.indexOf(linkRelationship) === -1 ? (CurrentUserUtils.ActiveDashboard?.colorScheme === ColorScheme.Dark ? "white" : "black") : linkColorList[linkRelationshipList.indexOf(linkRelationship)];
+        const strokeColor = currRelationshipIndex == -1 ? "black" : linkColorList[linkRelationshipList.indexOf(linkRelationship)];
+
+        //calculate stroke width/thickness based on the relative importance of the relationshipship (i.e. how many links the relationship has)
+        //thickness varies linearly from 3px to 12px for increasing link count
+        const strokeWidth: string = currRelationshipIndex == -1 ? "3px" : Math.floor(2 + 10 * (linkRelationshipSizes[currRelationshipIndex] / Math.max(...linkRelationshipSizes))) + "px";
+
         return !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<>
-            <path className="collectionfreeformlinkview-linkLine" style={{ opacity: this._opacity, strokeDasharray: "2 2", stroke: strokeColor }}
+            <path className="collectionfreeformlinkview-linkLine" style={{ opacity: this._opacity, /*strokeDasharray: "2 2",*/ stroke: strokeColor, strokeWidth: strokeWidth }}
                 d={`M ${pt1[0]} ${pt1[1]} C ${pt1[0] + pt1norm[0]} ${pt1[1] + pt1norm[1]}, ${pt2[0] + pt2norm[0]} ${pt2[1] + pt2norm[1]}, ${pt2[0]} ${pt2[1]}`} />
             {textX === undefined ? (null) : <text className="collectionfreeformlinkview-linkText" x={textX} y={textY} onPointerDown={this.pointerDown} >
                 {Field.toString(this.props.LinkDocs[0].description as any as Field)}
-- 
cgit v1.2.3-70-g09d2


From 8f1a6266cf0a728ab2b7df11d45a023de266fae4 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 7 Oct 2021 09:43:19 -0400
Subject: link menu ui tweaking.  edge case checks for linkrelationship stuff. 
 default links to have linkAutoMove

---
 src/Utils.ts                                           |  2 +-
 src/client/documents/Documents.ts                      |  2 ++
 src/client/util/LinkManager.ts                         | 11 +++--------
 .../collectionFreeForm/CollectionFreeFormLinkView.tsx  |  8 +++++---
 src/client/views/linking/LinkEditor.tsx                | 14 +++++++++++---
 src/client/views/linking/LinkMenuGroup.tsx             |  1 -
 src/client/views/linking/LinkMenuItem.tsx              | 18 +++++++++---------
 7 files changed, 31 insertions(+), 25 deletions(-)

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

diff --git a/src/Utils.ts b/src/Utils.ts
index 7ec4f69f3..53182cc9c 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -575,7 +575,7 @@ export function simulateMouseClick(element: Element | null | undefined, x: numbe
 
 export function DashColor(color: string) {
     try {
-        return Color(color.toLowerCase());
+        return color ? Color(color.toLowerCase()) : Color("transparent");
     } catch (e) {
         console.log("COLOR error:", e);
         return Color("red");
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 6d64b3286..da5c8efa9 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -191,6 +191,7 @@ export class DocumentOptions {
     opacity?: number;
     defaultBackgroundColor?: string;
     _isLinkButton?: boolean; // marks a document as a button that will follow its primary link when clicked
+    _linkAutoMove?: boolean; // whether link endpoint should move around the edges of a document to make shortest path to other link endpoint
     isFolder?: boolean;
     lastFrame?: number; // the last frame of a frame-based collection (e.g., progressive slide)
     activeFrame?: number; // the active frame of a document in a frame base collection
@@ -1106,6 +1107,7 @@ export namespace DocUtils {
             "_acl-Public": SharingPermissions.Augment,
             linkDisplay: true,
             _hidden: true,
+            _linkAutoMove: true,
             linkRelationship,
             _showCaption: "description",
             _showTitle: "linkRelationship",
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index 3f7f16113..90a8f2737 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -104,14 +104,9 @@ export class LinkManager {
 
     public createLinkrelationshipLists = () => {
         //create new lists for link relations and their associated colors if the lists don't already exist
-        if (!Doc.UserDoc().linkRelationshipList && !Doc.UserDoc().linkColorList) {
-            const linkRelationshipList = new List<string>();
-            const linkColorList = new List<string>();
-            const linkRelationshipSizes = new List<number>();
-            Doc.UserDoc().linkRelationshipList = linkRelationshipList;
-            Doc.UserDoc().linkColorList = linkColorList;
-            Doc.UserDoc().linkRelationshipSizes = linkRelationshipSizes;
-        }
+        !Doc.UserDoc().linkRelationshipList && (Doc.UserDoc().linkRelationshipList = new List<string>());
+        !Doc.UserDoc().linkColorList && (Doc.UserDoc().linkColorList = new List<string>());
+        !Doc.UserDoc().linkRelationshipSizes && (Doc.UserDoc().linkRelationshipSizes = new List<number>());
     }
 
     public addLink(linkDoc: Doc, checkExists = false) {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index 88cd0feb3..bb4cae8c6 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -189,15 +189,17 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
         const linkRelationshipSizes = Doc.UserDoc().linkRelationshipSizes as List<number>;
         const currRelationshipIndex = linkRelationshipList.indexOf(linkRelationship);
 
+        const linkSize = currRelationshipIndex === -1 || currRelationshipIndex >= linkRelationshipSizes.length ? -1 : linkRelationshipSizes[currRelationshipIndex];
+
         //access stroke color using index of the relationship in the color list (default black)
-        const strokeColor = currRelationshipIndex == -1 ? "black" : linkColorList[linkRelationshipList.indexOf(linkRelationship)];
+        const stroke = currRelationshipIndex === -1 || currRelationshipIndex >= linkColorList.length ? "black" : linkColorList[currRelationshipIndex];
 
         //calculate stroke width/thickness based on the relative importance of the relationshipship (i.e. how many links the relationship has)
         //thickness varies linearly from 3px to 12px for increasing link count
-        const strokeWidth: string = currRelationshipIndex == -1 ? "3px" : Math.floor(2 + 10 * (linkRelationshipSizes[currRelationshipIndex] / Math.max(...linkRelationshipSizes))) + "px";
+        const strokeWidth = linkSize === -1 ? "3px" : Math.floor(2 + 10 * (linkSize / Math.max(...linkRelationshipSizes))) + "px";
 
         return !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<>
-            <path className="collectionfreeformlinkview-linkLine" style={{ opacity: this._opacity, /*strokeDasharray: "2 2",*/ stroke: strokeColor, strokeWidth: strokeWidth }}
+            <path className="collectionfreeformlinkview-linkLine" style={{ opacity: this._opacity, /*strokeDasharray: "2 2",*/ stroke, strokeWidth }}
                 d={`M ${pt1[0]} ${pt1[1]} C ${pt1[0] + pt1norm[0]} ${pt1[1] + pt1norm[1]}, ${pt2[0] + pt2norm[0]} ${pt2[1] + pt2norm[1]}, ${pt2[0]} ${pt2[1]}`} />
             {textX === undefined ? (null) : <text className="collectionfreeformlinkview-linkText" x={textX} y={textY} onPointerDown={this.pointerDown} >
                 {Field.toString(this.props.LinkDocs[0].description as any as Field)}
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index 58c57a23b..5b5c3cd01 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -50,18 +50,26 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
             const linkColorList = StrListCast(Doc.UserDoc().linkColorList);
 
             // if the relationship does not exist in the list, add it and a corresponding unique randomly generated color 
-            if (linkRelationshipList && !linkRelationshipList.includes(value)) {
+            if (!linkRelationshipList?.includes(value)) {
                 linkRelationshipList.push(value);
                 linkRelationshipSizes.push(1);
                 const randColor = "rgb(" + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + ")";
                 linkColorList.push(randColor)
                 // if the relationship is already in the list AND the new rel is different from the prev rel, update the rel sizes
             } else if (linkRelationshipList && value != prevRelationship) {
+                const index = linkRelationshipList.indexOf(value);
                 //increment size of new relationship size
-                linkRelationshipSizes[linkRelationshipList.indexOf(value)] = linkRelationshipSizes[linkRelationshipList.indexOf(value)] + 1;
+                if (index !== -1 && index < linkRelationshipSizes.length) {
+                    const pvalue = linkRelationshipSizes[index];
+                    linkRelationshipSizes[index] = (pvalue === undefined || !Number.isFinite(pvalue) ? 1 : pvalue + 1);
+                }
                 //decrement the size of the previous relationship if it already exists (i.e. not default 'link' relationship upon link creation)
                 if (linkRelationshipList.includes(prevRelationship)) {
-                    linkRelationshipSizes[linkRelationshipList.indexOf(prevRelationship)] = linkRelationshipSizes[linkRelationshipList.indexOf(prevRelationship)] - 1;
+                    const pindex = linkRelationshipList.indexOf(prevRelationship);
+                    if (pindex !== -1 && pindex < linkRelationshipSizes.length) {
+                        const pvalue = linkRelationshipSizes[pindex];
+                        linkRelationshipSizes[pindex] = Math.max(0, (pvalue === undefined || !Number.isFinite(pvalue) ? 1 : pvalue - 1));
+                    }
                 }
 
             }
diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx
index cb6571f92..03377ad4e 100644
--- a/src/client/views/linking/LinkMenuGroup.tsx
+++ b/src/client/views/linking/LinkMenuGroup.tsx
@@ -31,7 +31,6 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
             if (RGBcolor) {
                 //set opacity to 0.25 by modifiying the rgb string
                 color = RGBcolor.slice(0, RGBcolor.length - 1) + ", 0.25)";
-                console.log(color);
             }
         }
         return color;
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index e0b20ef6f..f19064e49 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -165,19 +165,19 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
 
                         <div className="linkMenu-item-buttons" ref={this._buttonRef} >
 
-                            <Tooltip title={<><div className="dash-tooltip">{this.props.linkDoc.hidden ? "Show Anchor" : "Hide Anchor"}</div></>}>
-                                <div className="button" ref={this._editRef} onPointerDown={this.showAnchor} onClick={e => e.stopPropagation()}>
-                                    <FontAwesomeIcon className="fa-icon" icon={this.props.linkDoc.hidden ? "eye" : "eye-slash"} size="sm" /></div>
+                            <Tooltip title={<><div className="dash-tooltip">{this.props.linkDoc.hidden ? "Show Link Anchor" : "Hide Link Anchor"}</div></>}>
+                                <div className="button" ref={this._editRef} style={{ background: this.props.linkDoc.hidden ? "" : "#4476f7" /* $medium-blue */ }} onPointerDown={this.showAnchor} onClick={e => e.stopPropagation()}>
+                                    <FontAwesomeIcon className="fa-icon" icon={"eye"} size="sm" /></div>
                             </Tooltip>
 
-                            <Tooltip title={<><div className="dash-tooltip">{!this.props.linkDoc.linkDisplay ? "Show link" : "Hide link"}</div></>}>
-                                <div className="button" ref={this._editRef} onPointerDown={this.showLink} onClick={e => e.stopPropagation()}>
-                                    <FontAwesomeIcon className="fa-icon" icon={!this.props.linkDoc.linkDisplay ? "project-diagram" : "unlink"} size="sm" /></div>
+                            <Tooltip title={<><div className="dash-tooltip">{this.props.linkDoc.linkDisplay ? "Hide Link Line" : "Show Link Line"}</div></>}>
+                                <div className="button" ref={this._editRef} style={{ background: this.props.linkDoc.hidden ? "gray" : this.props.linkDoc.linkDisplay ? "#4476f7"/* $medium-blue */ : "" }} onPointerDown={this.showLink} onClick={e => e.stopPropagation()}>
+                                    <FontAwesomeIcon className="fa-icon" icon={"project-diagram"} size="sm" /></div>
                             </Tooltip>
 
-                            <Tooltip title={<><div className="dash-tooltip">{!this.props.linkDoc.linkAutoMove ? "Auto move dot" : "Freeze dot position"}</div></>}>
-                                <div className="button" ref={this._editRef} onPointerDown={this.autoMove} onClick={e => e.stopPropagation()}>
-                                    <FontAwesomeIcon className="fa-icon" icon={this.props.linkDoc.linkAutoMove ? "play" : "pause"} size="sm" /></div>
+                            <Tooltip title={<><div className="dash-tooltip">{this.props.linkDoc.linkAutoMove ? "Click to freeze link anchor position" : "Click to auto move link anchor"}</div></>}>
+                                <div className="button" ref={this._editRef} style={{ background: !this.props.linkDoc.linkAutoMove ? "" : "#4476f7" /* $medium-blue */ }} onPointerDown={this.autoMove} onClick={e => e.stopPropagation()}>
+                                    <FontAwesomeIcon className="fa-icon" icon={"play"} size="sm" /></div>
                             </Tooltip>
 
                             <Tooltip title={<><div className="dash-tooltip">Edit Link</div></>}>
-- 
cgit v1.2.3-70-g09d2

