aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/util/DocumentManager.ts16
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx97
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx135
-rw-r--r--src/client/views/nodes/DocumentView.tsx4
4 files changed, 181 insertions, 71 deletions
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index fc78993b8..85f8bf751 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -1,7 +1,7 @@
import { computed, observable } from 'mobx';
import { DocumentView } from '../views/nodes/DocumentView';
import { Doc, DocListCast, Opt } from '../../new_fields/Doc';
-import { FieldValue, Cast, NumCast, BoolCast } from '../../new_fields/Types';
+import { FieldValue, Cast, NumCast, BoolCast, StrCast } from '../../new_fields/Types';
import { listSpec } from '../../new_fields/Schema';
import { undoBatch } from './UndoManager';
import { CollectionDockingView } from '../views/collections/CollectionDockingView';
@@ -85,22 +85,26 @@ export class DocumentManager {
@computed
public get LinkedDocumentViews() {
let linked = DocumentManager.Instance.DocumentViews.filter(dv => dv.isSelected() || BoolCast(dv.props.Document.libraryBrush, false)).reduce((pairs, dv) => {
-
+ // console.log("FINDING LINKED DVs FOR", StrCast(dv.props.Document.title));
let linksList = LinkManager.Instance.findAllRelatedLinks(dv.props.Document);
if (linksList && linksList.length) {
pairs.push(...linksList.reduce((pairs, link) => {
if (link) {
let destination = LinkManager.Instance.findOppositeAnchor(link, dv.props.Document);
if (destination) {
- DocumentManager.Instance.getDocumentViews(destination).map(docView1 =>
- pairs.push({ a: dv, b: docView1, l: link }));
+ DocumentManager.Instance.getDocumentViews(destination).map(docView1 => {
+ // console.log("PUSHING LINK BETWEEN", StrCast(dv.props.Document.title), StrCast(docView1.props.Document.title));
+ // TODO: if any docviews are not in the same context, draw a proxy
+ // let sameContent = dv.props.ContainingCollectionView === docView1.props.ContainingCollectionView;
+ pairs.push({ anchor1View: dv, anchor2View: docView1, linkDoc: link });
+ });
}
}
return pairs;
- }, [] as { a: DocumentView, b: DocumentView, l: Doc }[]));
+ }, [] as { anchor1View: DocumentView, anchor2View: DocumentView, linkDoc: Doc }[]));
}
return pairs;
- }, [] as { a: DocumentView, b: DocumentView, l: Doc }[]);
+ }, [] as { anchor1View: DocumentView, anchor2View: DocumentView, linkDoc: Doc }[]);
return linked;
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index ddde8ece8..36ffac9c8 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -5,58 +5,81 @@ import { InkingControl } from "../../InkingControl";
import "./CollectionFreeFormLinkView.scss";
import React = require("react");
import v5 = require("uuid/v5");
+import { DocumentView } from "../../nodes/DocumentView";
export interface CollectionFreeFormLinkViewProps {
- A: Doc;
- B: Doc;
- LinkDocs: Doc[];
- addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
- removeDocument: (document: Doc) => boolean;
+ // anchor1: Doc;
+ // anchor2: Doc;
+ // LinkDocs: Doc[];
+ // addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
+ // removeDocument: (document: Doc) => boolean;
+ // sameContext: boolean;
+
+ sourceView: DocumentView;
+ targetView: DocumentView;
+ sameContext: boolean;
}
@observer
export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFormLinkViewProps> {
- onPointerDown = (e: React.PointerEvent) => {
- if (e.button === 0 && !InkingControl.Instance.selectedTool) {
- let a = this.props.A;
- let b = this.props.B;
- let x1 = NumCast(a.x) + (BoolCast(a.isMinimized, false) ? 5 : a[WidthSym]() / 2);
- let y1 = NumCast(a.y) + (BoolCast(a.isMinimized, false) ? 5 : a[HeightSym]() / 2);
- let x2 = NumCast(b.x) + (BoolCast(b.isMinimized, false) ? 5 : b[WidthSym]() / 2);
- let y2 = NumCast(b.y) + (BoolCast(b.isMinimized, false) ? 5 : b[HeightSym]() / 2);
- this.props.LinkDocs.map(l => {
- let width = l[WidthSym]();
- l.x = (x1 + x2) / 2 - width / 2;
- l.y = (y1 + y2) / 2 + 10;
- if (!this.props.removeDocument(l)) this.props.addDocument(l, false);
- });
- e.stopPropagation();
- e.preventDefault();
- }
- }
+ // onPointerDown = (e: React.PointerEvent) => {
+ // if (e.button === 0 && !InkingControl.Instance.selectedTool) {
+ // let a = this.props.A;
+ // let b = this.props.B;
+ // let x1 = NumCast(a.x) + (BoolCast(a.isMinimized, false) ? 5 : a[WidthSym]() / 2);
+ // let y1 = NumCast(a.y) + (BoolCast(a.isMinimized, false) ? 5 : a[HeightSym]() / 2);
+ // let x2 = NumCast(b.x) + (BoolCast(b.isMinimized, false) ? 5 : b[WidthSym]() / 2);
+ // let y2 = NumCast(b.y) + (BoolCast(b.isMinimized, false) ? 5 : b[HeightSym]() / 2);
+ // this.props.LinkDocs.map(l => {
+ // let width = l[WidthSym]();
+ // l.x = (x1 + x2) / 2 - width / 2;
+ // l.y = (y1 + y2) / 2 + 10;
+ // if (!this.props.removeDocument(l)) this.props.addDocument(l, false);
+ // });
+ // e.stopPropagation();
+ // e.preventDefault();
+ // }
+ // }
+
render() {
- let l = this.props.LinkDocs;
- let a = this.props.A;
- let b = this.props.B;
- let x1 = NumCast(a.x) + (BoolCast(a.isMinimized, false) ? 5 : NumCast(a.width) / NumCast(a.zoomBasis, 1) / 2);
- let y1 = NumCast(a.y) + (BoolCast(a.isMinimized, false) ? 5 : NumCast(a.height) / NumCast(a.zoomBasis, 1) / 2);
- let x2 = NumCast(b.x) + (BoolCast(b.isMinimized, false) ? 5 : NumCast(b.width) / NumCast(b.zoomBasis, 1) / 2);
- let y2 = NumCast(b.y) + (BoolCast(b.isMinimized, false) ? 5 : NumCast(b.height) / NumCast(b.zoomBasis, 1) / 2);
- let text = "";
- this.props.LinkDocs.map(l => text += StrCast(l.title) + "(" + StrCast(l.linkDescription) + "), ");
- text = "";
+ // let l = this.props.LinkDocs;
+ // let a = this.props.A;
+ // let b = this.props.B;
+ let a1 = this.props.sourceView;
+ let a2 = this.props.targetView;
+ let x1 = NumCast(a1.Document.x) + (BoolCast(a1.Document.isMinimized, false) ? 5 : NumCast(a1.Document.width) / NumCast(a1.Document.zoomBasis, 1) / 2);
+ let y1 = NumCast(a1.Document.y) + (BoolCast(a1.Document.isMinimized, false) ? 5 : NumCast(a1.Document.height) / NumCast(a1.Document.zoomBasis, 1) / 2);
+
+ let x2 = NumCast(a2.Document.x) + (BoolCast(a2.Document.isMinimized, false) ? 5 : NumCast(a2.Document.width) / NumCast(a2.Document.zoomBasis, 1) / 2);
+ let y2 = NumCast(a2.Document.y) + (BoolCast(a2.Document.isMinimized, false) ? 5 : NumCast(a2.Document.height) / NumCast(a2.Document.zoomBasis, 1) / 2);
+ if (!this.props.sameContext) {
+ x2 = x1 + 300;
+ y2 = y1 - 300;
+ }
+
+ // if (!this.props.sameContext) {
+ // console.log("not same context", StrCast(a1.title), StrCast(a2.title));
+ // x2 = x1 + 300;
+ // y2 = y2 + 300;
+ // } else {
+ // console.log("same context", StrCast(a1.title), StrCast(a2.title));
+ // }
+ // let text = "";
+ // this.props.LinkDocs.map(l => text += StrCast(l.title) + "(" + StrCast(l.linkDescription) + "), ");
+ // text = "";
return (
<>
- <line key="linkLine" className="collectionfreeformlinkview-linkLine"
- style={{ strokeWidth: `${2 * l.length / 2}` }}
+ <line className="collectionfreeformlinkview-linkLine"
+ style={{ strokeWidth: `${2 * 1 / 2}` }}
x1={`${x1}`} y1={`${y1}`}
x2={`${x2}`} y2={`${y2}`} />
+ {!this.props.sameContext ? <circle className="collectionfreeformlinkview-linkCircle" cx={x2} cy={y2} r={10}></circle> : <></>}
{/* <circle key="linkCircle" className="collectionfreeformlinkview-linkCircle"
cx={(x1 + x2) / 2} cy={(y1 + y2) / 2} r={8} onPointerDown={this.onPointerDown} /> */}
- <text key="linkText" textAnchor="middle" className="collectionfreeformlinkview-linkText" x={`${(x1 + x2) / 2}`} y={`${(y1 + y2) / 2}`}>
+ {/* <text key="linkText" textAnchor="middle" className="collectionfreeformlinkview-linkText" x={`${(x1 + x2) / 2}`} y={`${(y1 + y2) / 2}`}>
{text}
- </text>
+ </text> */}
</>
);
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index c4dd534ed..fc92c81d5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -92,40 +92,123 @@ export class CollectionFreeFormLinksView extends React.Component<CollectionViewP
return equalViews.filter(sv => sv.props.ContainingCollectionView && sv.props.ContainingCollectionView.props.Document === this.props.Document);
}
- @computed
- get uniqueConnections() {
- let connections = DocumentManager.Instance.LinkedDocumentViews.reduce((drawnPairs, connection) => {
- let srcViews = this.documentAnchors(connection.a);
- let targetViews = this.documentAnchors(connection.b);
- let possiblePairs: { a: Doc, b: Doc, }[] = [];
- srcViews.map(sv => targetViews.map(tv => possiblePairs.push({ a: sv.props.Document, b: tv.props.Document })));
- possiblePairs.map(possiblePair => {
- if (!drawnPairs.reduce((found, drawnPair) => {
- let match1 = (Doc.AreProtosEqual(possiblePair.a, drawnPair.a) && Doc.AreProtosEqual(possiblePair.b, drawnPair.b));
- let match2 = (Doc.AreProtosEqual(possiblePair.a, drawnPair.b) && Doc.AreProtosEqual(possiblePair.b, drawnPair.a));
- let match = match1 || match2;
- if (match && !drawnPair.l.reduce((found, link) => found || link[Id] === connection.l[Id], false)) {
- drawnPair.l.push(connection.l);
- }
- return match || found;
- }, false)) {
- drawnPairs.push({ a: possiblePair.a, b: possiblePair.b, l: [connection.l] })
+ // @computed
+ // get uniqueConnections() {
+ // // console.log("\n");
+ // let connections = DocumentManager.Instance.LinkedDocumentViews.reduce((drawnPairs, connection) => {
+ // // console.log("CONNECTION BETWEEN", StrCast(connection.anchor1View.props.Document.title), StrCast(connection.anchor2View.props.Document.title));
+ // let srcViews = this.documentAnchors(connection.anchor1View);
+ // // srcViews.forEach(sv => {
+ // // console.log("DOCANCHORS SRC", StrCast(connection.anchor1View.Document.title), StrCast(sv.Document.title));
+ // // });
+
+ // let targetViews = this.documentAnchors(connection.anchor2View);
+ // // targetViews.forEach(sv => {
+ // // console.log("DOCANCHORS TARG", StrCast(connection.anchor2View.Document.title), StrCast(sv.Document.title));
+ // // });
+
+ // // console.log("lengths", srcViews.length, targetViews.length);
+
+ // // srcViews.forEach(v => {
+ // // console.log("SOURCE VIEW", StrCast(v.props.Document.title));
+ // // });
+ // // targetViews.forEach(v => {
+ // // console.log("TARGET VIEW", StrCast(v.Document.title));
+ // // });
+
+ // let possiblePairs: { anchor1: Doc, anchor2: Doc }[] = [];
+ // // srcViews.map(sv => {
+ // // console.log("SOURCE VIEW", StrCast(sv.props.Document.title));
+ // // targetViews.map(tv => {
+ // // console.log("TARGET VIEW", StrCast(tv.props.Document.title));
+ // // // console.log("PUSHING PAIR", StrCast(sv.props.Document.title), StrCast(tv.props.Document.title));
+ // // possiblePairs.push({ anchor1: sv.props.Document, anchor2: tv.props.Document });
+ // // });
+ // // console.log("END\n");
+ // // });
+ // srcViews.forEach(sv => {
+ // // console.log("SOURCE VIEW", StrCast(sv.props.Document.title));
+ // targetViews.forEach(tv => {
+ // // console.log("TARGET VIEW", StrCast(tv.props.Document.title));
+ // // console.log("PUSHING PAIR", StrCast(sv.props.Document.title), StrCast(tv.props.Document.title));
+ // possiblePairs.push({ anchor1: sv.props.Document, anchor2: tv.props.Document });
+ // });
+ // // console.log("END\n");
+ // });
+ // // console.log("POSSIBLE PAIRS LENGTH", possiblePairs.length);
+ // possiblePairs.map(possiblePair => {
+ // // console.log("POSSIBLEPAIR", StrCast(possiblePair.anchor1.title), StrCast(possiblePair.anchor2.title));
+ // if (!drawnPairs.reduce((found, drawnPair) => {
+ // let match1 = (Doc.AreProtosEqual(possiblePair.anchor1, drawnPair.anchor1) && Doc.AreProtosEqual(possiblePair.anchor2, drawnPair.anchor2));
+ // let match2 = (Doc.AreProtosEqual(possiblePair.anchor1, drawnPair.anchor2) && Doc.AreProtosEqual(possiblePair.anchor2, drawnPair.anchor1));
+ // let match = match1 || match2;
+ // if (match && !drawnPair.linkDocs.reduce((found, link) => found || link[Id] === connection.linkDoc[Id], false)) {
+ // drawnPair.linkDocs.push(connection.linkDoc);
+ // }
+ // return match || found;
+ // }, false)) {
+ // drawnPairs.push({ anchor1: possiblePair.anchor1, anchor2: possiblePair.anchor2, linkDocs: [connection.linkDoc] });
+ // }
+ // });
+ // return drawnPairs;
+ // }, [] as { anchor1: Doc, anchor2: Doc, linkDocs: Doc[] }[]);
+ // return connections.map(c => {
+ // let x = c.linkDocs.reduce((p, l) => p + l[Id], "");
+ // return <CollectionFreeFormLinkView key={x} anchor1={c.anchor1} anchor2={c.anchor2} />;
+ // });
+ // }
+
+ findUniquePairs = (): JSX.Element[] => {
+ // console.log("FIND UNIQUE PAIRS");
+ let connections = DocumentManager.Instance.LinkedDocumentViews;
+
+ let unique: Array<{ sourceView: DocumentView, targetView: DocumentView, sameContext: boolean }> = [];
+ connections.forEach(c => {
+ let match1Index = unique.findIndex(u => (c.anchor1View === u.sourceView) && (c.anchor2View === u.targetView));
+ let match2Index = unique.findIndex(u => (c.anchor1View === u.targetView) && (c.anchor2View === u.sourceView));
+ let sameContext = c.anchor1View.props.ContainingCollectionView === c.anchor2View.props.ContainingCollectionView;
+
+ if (!(match1Index > -1 || match2Index > -1)) {
+ // if docview pair does not already exist in unique, push
+ unique.push({ sourceView: c.anchor1View, targetView: c.anchor2View, sameContext: sameContext });
+ } else {
+ // if docview pair exists in unique, push if not in same context
+ if (!sameContext) {
+ match1Index > -1 ? unique.push({ sourceView: c.anchor2View, targetView: c.anchor1View, sameContext: sameContext })
+ : unique.push({ sourceView: c.anchor1View, targetView: c.anchor2View, sameContext: sameContext });
}
- });
- return drawnPairs;
- }, [] as { a: Doc, b: Doc, l: Doc[] }[]);
- return connections.map(c => {
- let x = c.l.reduce((p, l) => p + l[Id], "");
- return <CollectionFreeFormLinkView key={x} A={c.a} B={c.b} LinkDocs={c.l}
- removeDocument={this.props.removeDocument} addDocument={this.props.addDocument} />;
+ }
+ });
+
+ console.log("\n UNIQUE");
+ unique.forEach(u => {
+ console.log(StrCast(u.sourceView.Document.title), StrCast(u.targetView.Document.title), u.sameContext);
+ });
+
+ // console.log("\n");
+
+ return unique.map(u => {
+ // TODO: make better key
+ let key = StrCast(u.sourceView.Document[Id]) + "-link-" + StrCast(u.targetView.Document[Id]) + "-" + Date.now() + Math.random();
+ let sourceIn = u.sourceView.props.ContainingCollectionView!.props.Document === this.props.Document;
+ let targetIn = u.targetView.props.ContainingCollectionView!.props.Document === this.props.Document;
+ let inContainer = u.sameContext ? sourceIn || targetIn : sourceIn;
+ if (inContainer) {
+ // console.log("key", key, StrCast(u.sourceView.Document.title), StrCast(u.targetView.Document.title));
+ return <CollectionFreeFormLinkView key={key} sourceView={u.sourceView} targetView={u.targetView} sameContext={u.sameContext} />;
+ } else {
+ return <div key={key}></div>;
+ }
});
}
render() {
+ this.findUniquePairs();
return (
<div className="collectionfreeformlinksview-container">
<svg className="collectionfreeformlinksview-svgCanvas">
- {this.uniqueConnections}
+ {/* {this.uniqueConnections} */}
+ {this.findUniquePairs()}
</svg>
{this.props.children}
</div>
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index c998b8ea6..e98392a18 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -319,8 +319,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
this._lastTap = Date.now();
}
- deleteClicked = (): void => { this.props.removeDocument && this.props.removeDocument(this.props.Document); }
- fieldsClicked = (): void => { this.props.addDocTab(Docs.KVPDocument(this.props.Document, { width: 300, height: 300 }), "onRight") };
+ deleteClicked = (): void => { this.props.removeDocument && this.props.removeDocument(this.props.Document); };
+ fieldsClicked = (): void => { this.props.addDocTab(Docs.KVPDocument(this.props.Document, { width: 300, height: 300 }), "onRight"); };
makeBtnClicked = (): void => {
let doc = Doc.GetProto(this.props.Document);
doc.isButton = !BoolCast(doc.isButton, false);