aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2024-02-07 18:32:22 -0500
committerbobzel <zzzman@gmail.com>2024-02-07 18:32:22 -0500
commit15f23f8b99b2e5ce48e7146c61d4d61b451875ad (patch)
tree1f89419b4166af6260815d20e9f26d2bbb948e48
parente3fde25014d523c5f43a138093718899fe17d108 (diff)
added back shiftkey to drag and embed. got rid of overlayplane link view. got rid of auto arrange. fixed text edit color for linkBox's
-rw-r--r--src/client/util/DocumentManager.ts37
-rw-r--r--src/client/util/DragManager.ts2
-rw-r--r--src/client/views/MainView.tsx4
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss12
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx318
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss13
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx25
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx35
-rw-r--r--src/client/views/collections/collectionFreeForm/index.ts12
-rw-r--r--src/client/views/global/globalScripts.ts5
-rw-r--r--src/client/views/nodes/LinkBox.tsx2
11 files changed, 17 insertions, 448 deletions
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 53d472c66..eada5af75 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -1,6 +1,6 @@
import { Howl } from 'howler';
import { action, computed, makeObservable, observable, ObservableSet, observe } from 'mobx';
-import { Doc, DocListCast, Opt } from '../../fields/Doc';
+import { Doc, Opt } from '../../fields/Doc';
import { AclAdmin, AclEdit, Animation, DocData } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { listSpec } from '../../fields/Schema';
@@ -28,8 +28,6 @@ export class DocumentManager {
//global holds all of the nodes (regardless of which collection they're in)
@observable _documentViews = new Set<DocumentView>();
@observable.shallow public CurrentlyLoading: Doc[] = [];
- @observable.shallow public LinkAnchorBoxViews: DocumentView[] = [];
- @observable.shallow public LinkedDocumentViews: { a: DocumentView; b: DocumentView; l: Doc }[] = [];
@computed public get DocumentViews() {
return Array.from(this._documentViews).filter(view => !(view.ComponentView instanceof KeyValueBox) && (!LightboxView.LightboxDoc || LightboxView.Contains(view)));
}
@@ -90,37 +88,14 @@ export class DocumentManager {
@action
public AddView = (view: DocumentView) => {
- if (view._props.LayoutTemplateString?.includes(KeyValueBox.name)) return;
- if (view._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) {
- const viewAnchorIndex = view._props.LayoutTemplateString.includes('link_anchor_2') ? 'link_anchor_2' : 'link_anchor_1';
- const link = view.Document;
- this.LinkAnchorBoxViews?.filter(dv => Doc.AreProtosEqual(dv.Document, link) && !dv._props.LayoutTemplateString?.includes(viewAnchorIndex)).forEach(otherView =>
- this.LinkedDocumentViews.push({
- a: viewAnchorIndex === 'link_anchor_2' ? otherView : view,
- b: viewAnchorIndex === 'link_anchor_2' ? view : otherView,
- l: link,
- })
- );
- this.LinkAnchorBoxViews.push(view);
- } else {
+ if (!view._props.LayoutTemplateString?.includes(KeyValueBox.name) &&
+ !view._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) {
this.AddDocumentView(view);
- }
- this.callAddViewFuncs(view);
+ this.callAddViewFuncs(view);
+ } // prettier-ignore
};
public RemoveView = action((view: DocumentView) => {
- this.LinkedDocumentViews.slice().forEach(
- action(pair => {
- if (pair.a === view || pair.b === view) {
- const li = this.LinkedDocumentViews.indexOf(pair);
- li !== -1 && this.LinkedDocumentViews.splice(li, 1);
- }
- })
- );
-
- if (view._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) {
- const index = this.LinkAnchorBoxViews.indexOf(view);
- this.LinkAnchorBoxViews.splice(index, 1);
- } else {
+ if (!view._props.LayoutTemplateString?.includes(KeyValueBox.name) && !view._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) {
this.DeleteDocumentView(view);
}
SelectionManager.DeselectView(view);
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index a6ad0f1b3..78356888a 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -504,7 +504,7 @@ export namespace DragManager {
const moveHandler = (e: PointerEvent) => {
e.preventDefault(); // required or dragging text menu link item ends up dragging the link button as native drag/drop
if (dragData instanceof DocumentDragData) {
- dragData.userDropAction = e.ctrlKey && e.altKey ? 'copy' : e.ctrlKey ? 'embed' : dragData.defaultDropAction;
+ dragData.userDropAction = e.ctrlKey && e.altKey ? 'copy' : e.shiftKey ? 'move' : e.ctrlKey ? 'embed' : dragData.defaultDropAction;
}
if (((e.target as any)?.className === 'lm_tabs' || (e.target as any)?.className === 'lm_header') && dragData.draggedDocuments.length === 1) {
if (!startWindowDragTimer) {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index eca0aca4c..efe906981 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -10,6 +10,7 @@ import * as React from 'react';
import '../../../node_modules/browndash-components/dist/styles/global.min.css';
import { Utils, emptyFunction, lightOrDark, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../Utils';
import { Doc, DocListCast, Opt } from '../../fields/Doc';
+import { DocData } from '../../fields/DocSymbols';
import { DocCast, StrCast } from '../../fields/Types';
import { DocServer } from '../DocServer';
import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager';
@@ -50,7 +51,6 @@ import { CollectionDockingView } from './collections/CollectionDockingView';
import { CollectionMenu } from './collections/CollectionMenu';
import { TabDocView } from './collections/TabDocView';
import './collections/TreeView.scss';
-import { CollectionFreeFormLinksView } from './collections/collectionFreeForm';
import { MarqueeOptionsMenu } from './collections/collectionFreeForm/MarqueeOptionsMenu';
import { CollectionLinearView } from './collections/collectionLinear';
import { LinkMenu } from './linking/LinkMenu';
@@ -72,7 +72,6 @@ import { PresBox } from './nodes/trails';
import { AnchorMenu } from './pdf/AnchorMenu';
import { GPTPopup } from './pdf/GPTPopup/GPTPopup';
import { TopBar } from './topbar/TopBar';
-import { DocData } from '../../fields/DocSymbols';
const { default: { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
const _global = (window /* browser */ || global) /* node */ as any;
@@ -1037,7 +1036,6 @@ export class MainView extends ObservableReactComponent<{}> {
{/* <InkTranscription /> */}
{this.snapLines}
<LightboxView key="lightbox" PanelWidth={this._windowWidth} PanelHeight={this._windowHeight} maxBorder={[200, 50]} />
- <CollectionFreeFormLinksView />
<OverlayView />
<GPTPopup key="gptpopup" />
<SchemaCSVPopUp key="schemacsvpopup" />
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss
deleted file mode 100644
index b44acfce8..000000000
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss
+++ /dev/null
@@ -1,12 +0,0 @@
-.collectionfreeformlinkview-linkLine {
- stroke: black;
- opacity: 0.8;
- stroke-width: 3px;
- transition: opacity 0.5s ease-in;
- fill: transparent;
-}
-.collectionfreeformlinkview-linkText {
- stroke: rgb(0, 0, 0);
- pointer-events: all;
- cursor: move;
-}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
deleted file mode 100644
index a45a1fb0f..000000000
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ /dev/null
@@ -1,318 +0,0 @@
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import { Doc, Field } from '../../../../fields/Doc';
-import { Brushed, DocCss } from '../../../../fields/DocSymbols';
-import { Id } from '../../../../fields/FieldSymbols';
-import { List } from '../../../../fields/List';
-import { Cast, NumCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils';
-import { LinkManager } from '../../../util/LinkManager';
-import { SelectionManager } from '../../../util/SelectionManager';
-import { SettingsManager } from '../../../util/SettingsManager';
-import { SnappingManager } from '../../../util/SnappingManager';
-import { Colors } from '../../global/globalEnums';
-import { DocumentView } from '../../nodes/DocumentView';
-import { ObservableReactComponent } from '../../ObservableReactComponent';
-import './CollectionFreeFormLinkView.scss';
-
-export interface CollectionFreeFormLinkViewProps {
- A: DocumentView;
- B: DocumentView;
- LinkDocs: Doc[];
-}
-
-@observer
-export class CollectionFreeFormLinkView extends ObservableReactComponent<CollectionFreeFormLinkViewProps> {
- @observable _opacity: number = 0;
- @observable _start = 0;
- _anchorDisposer: IReactionDisposer | undefined;
- _timeout: NodeJS.Timeout | undefined;
- constructor(props: any) {
- super(props);
- makeObservable(this);
- }
-
- componentWillUnmount() {
- this._anchorDisposer?.();
- }
- @action timeout: any = action(() => Date.now() < this._start++ + 1000 && (this._timeout = setTimeout(this.timeout, 25)));
- componentDidMount() {
- this._anchorDisposer = reaction(
- () => [
- this._props.A.screenToViewTransform(),
- Cast(Cast(Cast(this._props.A.Document, Doc, null)?.link_anchor_1, Doc, null)?.annotationOn, Doc, null)?.layout_scrollTop,
- Cast(Cast(Cast(this._props.A.Document, Doc, null)?.link_anchor_1, Doc, null)?.annotationOn, Doc, null)?.[DocCss],
- this._props.B.screenToViewTransform(),
- Cast(Cast(Cast(this._props.A.Document, Doc, null)?.link_anchor_2, Doc, null)?.annotationOn, Doc, null)?.layout_scrollTop,
- Cast(Cast(Cast(this._props.A.Document, Doc, null)?.link_anchor_2, Doc, null)?.annotationOn, Doc, null)?.[DocCss],
- ],
- action(() => {
- this._start = Date.now();
- this._timeout && clearTimeout(this._timeout);
- this._timeout = setTimeout(this.timeout, 25);
- setTimeout(this.placeAnchors, 10); // when docs are dragged, their transforms will update before a render has been performed. placeanchors needs to come after a render to find things in the dom. a 0 timeout will still come before the render
- }),
- { fireImmediately: true }
- );
- }
- placeAnchors = () => {
- const { A, B, LinkDocs } = this._props;
- const linkDoc = LinkDocs[0];
- if (SnappingManager.IsDragging || !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.link_displayLine || Doc.UserDoc().showLinkLines)) && (this._opacity = 0.05)),
- 750
- ); // this will unhighlight the link line.
- 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);
-
- // really hacky stuff to make the LinkAnchorBox display where we want it to:
- // if there's an element in the DOM with a classname containing a link anchor's id,
- // then that DOM element is a hyperlink source for the current anchor and we want to place our link box at it's top right
- // otherwise, we just use the computed nearest point on the document boundary to the target Document
- const targetAhyperlink = Array.from(window.document.getElementsByClassName((linkDoc.link_anchor_1 as Doc)[Id])).lastElement();
- const targetBhyperlink = Array.from(window.document.getElementsByClassName((linkDoc.link_anchor_2 as Doc)[Id])).lastElement();
- if ((!targetAhyperlink && !a.width) || (!targetBhyperlink && !b.width)) return;
- if (!targetAhyperlink) {
- if (linkDoc.link_autoMoveAnchors) {
- linkDoc.link_anchor_1_x = ((apt.point.x - aleft) / awidth) * 100;
- linkDoc.link_anchor_1_y = ((apt.point.y - atop) / aheight) * 100;
- }
- } else {
- const m = targetAhyperlink.getBoundingClientRect();
- const mp = A.screenToViewTransform().transformPoint(m.right, m.top + 5);
- const mpx = mp[0] / A._props.PanelWidth();
- const mpy = mp[1] / A._props.PanelHeight();
- if (mpx >= 0 && mpx <= 1) linkDoc.link_anchor_1_x = mpx * 100;
- if (mpy >= 0 && mpy <= 1) linkDoc.link_anchor_1_y = mpy * 100;
- if (getComputedStyle(targetAhyperlink).fontSize === '0px') linkDoc.opacity = 0;
- else linkDoc.opacity = 1;
- }
- if (!targetBhyperlink) {
- if (linkDoc.link_autoMoveAnchors) {
- linkDoc.link_anchor_2_x = ((bpt.point.x - bleft) / bwidth) * 100;
- linkDoc.link_anchor_2_y = ((bpt.point.y - btop) / bheight) * 100;
- }
- } else {
- const m = targetBhyperlink.getBoundingClientRect();
- const mp = B.screenToViewTransform().transformPoint(m.right, m.top + 5);
- const mpx = mp[0] / B._props.PanelWidth();
- const mpy = mp[1] / B._props.PanelHeight();
- if (mpx >= 0 && mpx <= 1) linkDoc.link_anchor_2_x = mpx * 100;
- if (mpy >= 0 && mpy <= 1) linkDoc.link_anchor_2_y = mpy * 100;
- if (getComputedStyle(targetBhyperlink).fontSize === '0px') linkDoc.opacity = 0;
- else linkDoc.opacity = 1;
- }
- };
-
- pointerDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(
- this,
- e,
- (e, down, delta) => {
- this._props.LinkDocs[0].link_relationship_OffsetX = NumCast(this._props.LinkDocs[0].link_relationship_OffsetX) + delta[0];
- this._props.LinkDocs[0].link_relationship_OffsetY = NumCast(this._props.LinkDocs[0].link_relationship_OffsetY) + delta[1];
- return false;
- },
- emptyFunction,
- action(() => {
- SelectionManager.DeselectAll();
- SelectionManager.SelectSchemaViewDoc(this._props.LinkDocs[0], true);
- LinkManager.Instance.currentLink = this._props.LinkDocs[0];
- this.toggleProperties();
- // OverlayView.Instance.addElement(
- // <LinkEditor sourceDoc={this._props.A.Document} linkDoc={this._props.LinkDocs[0]}
- // showLinks={action(() => { })}
- // />, { x: 300, y: 300 });
- })
- );
- };
-
- visibleY = (el: any) => {
- let rect = el.getBoundingClientRect();
- const top = rect.top,
- height = rect.height;
- var el = el.parentNode;
- while (el && el !== document.body) {
- if (el.className === 'tabDocView-content') break;
- rect = el.getBoundingClientRect?.();
- if (rect?.width) {
- if (top <= rect.bottom === false && getComputedStyle(el).overflow === 'hidden') return rect.bottom;
- // Check if the element is out of view due to a container scrolling
- if (top + height <= rect.top && getComputedStyle(el).overflow === 'hidden') return rect.top;
- }
- el = el.parentNode;
- }
- // Check its within the document viewport
- return top; //top <= document.documentElement.clientHeight && getComputedStyle(document.documentElement).overflow === "hidden";
- };
- visibleX = (el: any) => {
- let rect = el.getBoundingClientRect();
- const left = rect.left,
- width = rect.width;
- var el = el.parentNode;
- while (el && el !== document.body) {
- rect = el?.getBoundingClientRect();
- if (rect?.width) {
- if (left <= rect.right === false && getComputedStyle(el).overflow === 'hidden') return rect.right;
- // Check if the element is out of view due to a container scrolling
- if (left + width <= rect.left && getComputedStyle(el).overflow === 'hidden') return rect.left;
- }
- el = el.parentNode;
- }
- // Check its within the document viewport
- return left; //top <= document.documentElement.clientHeight && getComputedStyle(document.documentElement).overflow === "hidden";
- };
-
- @action
- toggleProperties = () => {
- if ((SettingsManager.Instance.propertiesWidth ?? 0) < 100) {
- SettingsManager.Instance.propertiesWidth = 250;
- }
- };
-
- @action
- onClickLine = () => {
- SelectionManager.DeselectAll();
- SelectionManager.SelectSchemaViewDoc(this._props.LinkDocs[0], true);
- LinkManager.Instance.currentLink = this._props.LinkDocs[0];
- this.toggleProperties();
- };
-
- @computed.struct get renderData() {
- this._start;
- SnappingManager.IsDragging;
- const { A, B, LinkDocs } = this._props;
- if (!A.ContentDiv || !B.ContentDiv || !LinkDocs.length) return undefined;
- 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;
- for (let apdiv = adiv; apdiv; apdiv = apdiv.parentElement as any) if ((apdiv as any).hidden) return;
- for (let bpdiv = bdiv; bpdiv; bpdiv = bpdiv.parentElement as any) if ((bpdiv as any).hidden) return;
- const a = adiv.getBoundingClientRect();
- const b = bdiv.getBoundingClientRect();
- const atop = this.visibleY(adiv);
- const btop = this.visibleY(bdiv);
- 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 aleft = this.visibleX(adiv);
- const bleft = this.visibleX(bdiv);
- const aclipped = aleft !== a.left || atop !== a.top;
- const bclipped = bleft !== b.left || btop !== b.top;
- if (aclipped && bclipped) return undefined;
- const clipped = aclipped || bclipped;
- const pt1inside = NumCast(LinkDocs[0].link_anchor_1_x) % 100 !== 0 && NumCast(LinkDocs[0].link_anchor_1_y) % 100 !== 0;
- const pt2inside = NumCast(LinkDocs[0].link_anchor_2_x) % 100 !== 0 && NumCast(LinkDocs[0].link_anchor_2_y) % 100 !== 0;
- const pt1 = [aleft + a.width / 2, atop + a.height / 2];
- const pt2 = [bleft + b.width / 2, btop + b.width / 2];
- const pt2vec = pt2inside ? [-0.7071, 0.7071] : [(bDocBounds.left + bDocBounds.right) / 2 - pt2[0], (bDocBounds.top + bDocBounds.bottom) / 2 - pt2[1]];
- const pt1vec = pt1inside ? [-0.7071, 0.7071] : [(aDocBounds.left + aDocBounds.right) / 2 - pt1[0], (aDocBounds.top + aDocBounds.bottom) / 2 - pt1[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] : [-(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];
- const pt2normalized = [pt2norm[0] / pt2normlen, pt2norm[1] / pt2normlen];
- const aActive = A.IsSelected || A.Document[Brushed];
- const bActive = B.IsSelected || B.Document[Brushed];
-
- const textX = (Math.min(pt1[0], pt2[0]) + Math.max(pt1[0], pt2[0])) / 2 + NumCast(LinkDocs[0].link_relationship_OffsetX);
- const textY = (pt1[1] + pt2[1]) / 2 + NumCast(LinkDocs[0].link_relationship_OffsetY);
- const link = this._props.LinkDocs[0];
- return {
- a,
- b,
- pt1norm,
- pt2norm,
- aActive,
- bActive,
- textX,
- textY,
- // fully connected
- // pt1,
- // pt2,
- // this code adds space between links
- pt1: link.link_displayArrow ? [pt1[0] + pt1normalized[0] * 3 * NumCast(link.link_displayArrow_scale, 4), pt1[1] + pt1normalized[1] * 3 * NumCast(link.link_displayArrow_scale, 3)] : pt1,
- pt2: link.link_displayArrow ? [pt2[0] + pt2normalized[0] * 3 * NumCast(link.link_displayArrow_scale, 4), pt2[1] + pt2normalized[1] * 3 * NumCast(link.link_displayArrow_scale, 3)] : pt2,
- };
- }
-
- render() {
- if (!this.renderData) return null;
-
- const link = this._props.LinkDocs[0];
- const { a, b, pt1norm, pt2norm, aActive, bActive, textX, textY, pt1, pt2 } = this.renderData;
- const linkRelationship = Field.toString(link?.link_relationship as any as Field); //get string representing relationship
- const linkRelationshipList = Doc.UserDoc().link_relationshipList as List<string>;
- const linkColorList = Doc.UserDoc().link_ColorList as List<string>;
- const linkRelationshipSizes = Doc.UserDoc().link_relationshipSizes as List<number>;
- const currRelationshipIndex = linkRelationshipList.indexOf(linkRelationship);
- const linkDescription = Field.toString(link.link_description as any as Field).split('\n')[0];
-
- const linkSize = Doc.noviceMode || currRelationshipIndex === -1 || currRelationshipIndex >= linkRelationshipSizes.length ? -1 : linkRelationshipSizes[currRelationshipIndex];
-
- //access stroke color using index of the relationship in the color list (default black)
- const stroke = currRelationshipIndex === -1 || currRelationshipIndex >= linkColorList.length ? StrCast(link._backgroundColor, 'black') : linkColorList[currRelationshipIndex];
- // const hexStroke = this.rgbToHex(stroke)
-
- //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 = linkSize === -1 ? '3px' : Math.floor(2 + 10 * (linkSize / Math.max(...linkRelationshipSizes))) + 'px';
-
- const arrowScale = NumCast(link.link_displayArrow_scale, 3);
- return link.opacity === 0 || !a.width || !b.width || (!(Doc.UserDoc().showLinkLines || link.link_displayLine) && !aActive && !bActive) ? null : (
- <>
- <defs>
- <marker id={`${link[Id] + 'arrowhead'}`} markerWidth={`${4 * arrowScale}`} markerHeight={`${3 * arrowScale}`} refX="0" refY={`${1.5 * arrowScale}`} orient="auto">
- <polygon points={`0 0, ${3 * arrowScale} ${1.5 * arrowScale}, 0 ${3 * arrowScale}`} fill={stroke} />
- </marker>
- <filter id="outline">
- <feMorphology in="SourceAlpha" result="expanded" operator="dilate" radius="1" />
- <feFlood floodColor={`${Colors.DARK_GRAY}`} />
- <feComposite in2="expanded" operator="in" />
- <feComposite in="SourceGraphic" />
- </filter>
- <filter x="0" y="0" width="1" height="1" id={`${link[Id] + 'background'}`}>
- <feFlood floodColor={`${StrCast(link._backgroundColor, 'white')}`} result="bg" />
- <feMerge>
- <feMergeNode in="bg" />
- <feMergeNode in="SourceGraphic" />
- </feMerge>
- </filter>
- </defs>
- <path
- filter={LinkManager.Instance.currentLink === link ? 'url(#outline)' : ''}
- fill="pink"
- stroke="antiquewhite"
- strokeWidth="4"
- className="collectionfreeformlinkview-linkLine"
- style={{ pointerEvents: 'visibleStroke', opacity: this._opacity, stroke, strokeWidth }}
- onClick={this.onClickLine}
- 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]}`}
- markerEnd={link.link_displayArrow ? `url(#${link[Id] + 'arrowhead'})` : ''}
- />
- {textX === undefined || !linkDescription ? null : (
- <text filter={`url(#${link[Id] + 'background'})`} className="collectionfreeformlinkview-linkText" x={textX} y={textY} onPointerDown={this.pointerDown}>
- <tspan>&nbsp;</tspan>
- <tspan dy="2">{linkDescription.substring(0, 50) + (linkDescription.length > 50 ? '...' : '')}</tspan>
- <tspan dy="2">&nbsp;</tspan>
- </text>
- )}
- </>
- );
- }
-}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss
deleted file mode 100644
index 4ada1731f..000000000
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss
+++ /dev/null
@@ -1,13 +0,0 @@
-// TODO: change z-index to -1 when a modal is active?
-
-.collectionfreeformlinksview-svgCanvas {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- pointer-events: none;
-}
-.collectionfreeformlinksview-container {
- pointer-events: none;
-}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
deleted file mode 100644
index e5b6c366f..000000000
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { computed } from 'mobx';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import { Id } from '../../../../fields/FieldSymbols';
-import { DocumentManager } from '../../../util/DocumentManager';
-import { LightboxView } from '../../LightboxView';
-import { CollectionFreeFormLinkView } from './CollectionFreeFormLinkView';
-import './CollectionFreeFormLinksView.scss';
-
-@observer
-export class CollectionFreeFormLinksView extends React.Component {
- @computed get uniqueConnections() {
- return Array.from(new Set(DocumentManager.Instance.LinkedDocumentViews))
- .filter(c => !LightboxView.LightboxDoc || (LightboxView.Contains(c.a) && LightboxView.Contains(c.b)))
- .map(c => <CollectionFreeFormLinkView key={c.l[Id]} A={c.a} B={c.b} LinkDocs={[c.l]} />);
- }
-
- render() {
- return (
- <div className="collectionfreeformlinksview-container">
- <svg className="collectionfreeformlinksview-svgCanvas">{this.uniqueConnections}</svg>
- </div>
- );
- }
-}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 61fd5fd05..e4c71a086 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -10,6 +10,7 @@ import { DocData, Height, Width } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { InkData, InkField, InkTool, PointData, Segment } from '../../../../fields/InkField';
import { List } from '../../../../fields/List';
+import { RichTextField } from '../../../../fields/RichTextField';
import { listSpec } from '../../../../fields/Schema';
import { ScriptField } from '../../../../fields/ScriptField';
import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
@@ -22,8 +23,8 @@ import { Docs, DocUtils } from '../../../documents/Documents';
import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
import { DocumentManager } from '../../../util/DocumentManager';
import { DragManager, dropActionType } from '../../../util/DragManager';
-import { FollowLinkScript } from '../../../util/LinkFollower';
import { ReplayMovements } from '../../../util/ReplayMovements';
+import { CompileScript } from '../../../util/Scripting';
import { ScriptingGlobals } from '../../../util/ScriptingGlobals';
import { SelectionManager } from '../../../util/SelectionManager';
import { freeformScrollMode } from '../../../util/SettingsManager';
@@ -53,8 +54,6 @@ import { CollectionFreeFormPannableContents } from './CollectionFreeFormPannable
import { CollectionFreeFormRemoteCursors } from './CollectionFreeFormRemoteCursors';
import './CollectionFreeFormView.scss';
import { MarqueeView } from './MarqueeView';
-import { RichTextField } from '../../../../fields/RichTextField';
-import { CompileScript } from '../../../util/Scripting';
export interface collectionFreeformViewProps {
NativeWidth?: () => number;
@@ -377,28 +376,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
!d._keepZWhenDragged && (d.zIndex = zsorted.length + 1 + i); // bringToFront
}
- if (this.layoutDoc._autoArrange || de.metaKey) {
- const sorted = this.childLayoutPairs.slice().sort((a, b) => NumCast(a.layout.y) - NumCast(b.layout.y));
- sorted.splice(
- sorted.findIndex(pair => pair.layout === refDoc),
- 1
- );
- if (sorted.length && refDoc && NumCast(sorted[0].layout.y) < NumCast(refDoc.y)) {
- const topIndexed = NumCast(refDoc.y) < NumCast(sorted[0].layout.y) + NumCast(sorted[0].layout._height) / 2;
- const deltay = sorted.length > 1 ? NumCast(refDoc.y) - (NumCast(sorted[0].layout.y) + (topIndexed ? 0 : NumCast(sorted[0].layout._height))) : 0;
- const deltax = sorted.length > 1 ? NumCast(refDoc.x) - NumCast(sorted[0].layout.x) : 0;
-
- let lastx = NumCast(refDoc.x);
- let lasty = NumCast(refDoc.y) + (topIndexed ? 0 : NumCast(refDoc._height));
- runInAction(() =>
- sorted.slice(1).forEach((pair, i) => {
- lastx = pair.layout.x = lastx + deltax;
- lasty = (pair.layout.y = lasty + deltay) + (topIndexed ? 0 : NumCast(pair.layout._height));
- })
- );
- }
- }
-
(docDragData.droppedDocuments.length === 1 || de.shiftKey) && this.updateClusterDocs(docDragData.droppedDocuments);
return true;
}
@@ -1000,7 +977,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
if (!this.isAnnotationOverlay && clamp) {
// this section wraps the pan position, horizontally and/or vertically whenever the content is panned out of the viewing bounds
- const docs = this.childLayoutPairs.map(pair => pair.layout).filter(doc => doc instanceof Doc);
+ const docs = this.childLayoutPairs.map(pair => pair.layout).filter(doc => doc instanceof Doc && doc.type !== DocumentType.LINK);
const measuredDocs = docs
.map(doc => ({ pos: { x: NumCast(doc.x), y: NumCast(doc.y) }, size: { width: NumCast(doc._width), height: NumCast(doc._height) } }))
.filter(({ pos, size }) => pos && size)
@@ -1651,12 +1628,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const appearanceItems = appearance && 'subitems' in appearance ? appearance.subitems : [];
!this.Document.isGroup && appearanceItems.push({ description: 'Reset View', event: this.resetView, icon: 'compress-arrows-alt' });
!this.Document.isGroup && appearanceItems.push({ description: 'Toggle Auto Reset View', event: this.toggleResetView, icon: 'compress-arrows-alt' });
- !Doc.noviceMode &&
- appearanceItems.push({
- description: 'Toggle auto arrange',
- event: () => (this.layoutDoc._autoArrange = !this.layoutDoc._autoArrange),
- icon: 'compress-arrows-alt',
- });
if (this._props.setContentViewBox === emptyFunction) {
!appearance && ContextMenu.Instance.addItem({ description: 'Appearance...', subitems: appearanceItems, icon: 'eye' });
return;
diff --git a/src/client/views/collections/collectionFreeForm/index.ts b/src/client/views/collections/collectionFreeForm/index.ts
index 702dc8d42..9a54ce63a 100644
--- a/src/client/views/collections/collectionFreeForm/index.ts
+++ b/src/client/views/collections/collectionFreeForm/index.ts
@@ -1,7 +1,5 @@
-export * from "./CollectionFreeFormLayoutEngines";
-export * from "./CollectionFreeFormLinkView";
-export * from "./CollectionFreeFormLinksView";
-export * from "./CollectionFreeFormRemoteCursors";
-export * from "./CollectionFreeFormView";
-export * from "./MarqueeOptionsMenu";
-export * from "./MarqueeView"; \ No newline at end of file
+export * from './CollectionFreeFormLayoutEngines';
+export * from './CollectionFreeFormRemoteCursors';
+export * from './CollectionFreeFormView';
+export * from './MarqueeOptionsMenu';
+export * from './MarqueeView';
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index 0541a9ca7..51672513b 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -127,11 +127,6 @@ ScriptingGlobals.add(function showFreeform(attr: 'flashcards' | 'center' | 'grid
checkResult: (doc:Doc) => BoolCast(doc?._freeform_useClusters, false),
setDoc: (doc:Doc,dv:DocumentView) => doc._freeform_useClusters = !doc._freeform_useClusters,
}],
- ['arrange', {
- waitForRender: true, // flags that undo batch should terminate after a re-render giving the script the chance to fire
- checkResult: (doc:Doc) => BoolCast(doc?._autoArrange, false),
- setDoc: (doc:Doc,dv:DocumentView) => doc._autoArrange = !doc._autoArrange,
- }],
['flashcards', {
checkResult: (doc:Doc) => BoolCast(Doc.UserDoc().defaultToFlashcards, false),
setDoc: (doc:Doc,dv:DocumentView) => Doc.UserDoc().defaultToFlashcards = !Doc.UserDoc().defaultToFlashcards,
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 0788e5adc..4f1d12c9b 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -154,7 +154,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
paddingRight: 4,
paddingTop: 3,
paddingBottom: 3,
- background: DashColor(highlightColor || color)
+ background: DashColor((!this.DocumentView?.().isSelected() && highlightColor) || color)
.fade(0.5)
.toString(),
}}>