aboutsummaryrefslogtreecommitdiff
path: root/src/client/util
diff options
context:
space:
mode:
authoryipstanley <stanley_yip@brown.edu>2019-10-26 15:35:56 -0400
committeryipstanley <stanley_yip@brown.edu>2019-10-26 15:35:56 -0400
commit24031b32402f19932d293bdc3eb483235cff820a (patch)
treeab1cb93f50eafeb1a4cf07e588aed971700c96b5 /src/client/util
parent3cff8e7d101a528e392d885420de118cccca6ae5 (diff)
parent2786a2e4b33ff874f320697b89fecec3105df201 (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into interaction_stanley
Diffstat (limited to 'src/client/util')
-rw-r--r--src/client/util/DictationManager.ts5
-rw-r--r--src/client/util/DocumentManager.ts48
-rw-r--r--src/client/util/DragManager.ts27
-rw-r--r--src/client/util/DropConverter.ts46
-rw-r--r--src/client/util/Import & Export/DirectoryImportBox.tsx2
-rw-r--r--src/client/util/LinkManager.ts19
6 files changed, 88 insertions, 59 deletions
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts
index 182cfb70a..6bbd3d0ed 100644
--- a/src/client/util/DictationManager.ts
+++ b/src/client/util/DictationManager.ts
@@ -6,7 +6,7 @@ import { DocumentType } from "../documents/DocumentTypes";
import { Doc, Opt } from "../../new_fields/Doc";
import { List } from "../../new_fields/List";
import { Docs } from "../documents/Documents";
-import { CollectionViewType } from "../views/collections/CollectionBaseView";
+import { CollectionViewType } from "../views/collections/CollectionView";
import { Cast, CastCtor } from "../../new_fields/Types";
import { listSpec } from "../../new_fields/Schema";
import { AudioField, ImageField } from "../../new_fields/URLField";
@@ -64,7 +64,7 @@ export namespace DictationManager {
const intraSession = ". ";
const interSession = " ... ";
- let isListening = false;
+ export let isListening = false;
let isManuallyStopped = false;
let current: string | undefined = undefined;
@@ -200,6 +200,7 @@ export namespace DictationManager {
if (!isListening || !recognizer) {
return;
}
+ isListening = false;
isManuallyStopped = true;
salvageSession ? recognizer.stop() : recognizer.abort();
// let main = MainView.Instance;
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 00de39671..346e88f40 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -1,5 +1,5 @@
import { action, computed, observable } from 'mobx';
-import { Doc, DocListCastAsync } from '../../new_fields/Doc';
+import { Doc, DocListCastAsync, DocListCast } from '../../new_fields/Doc';
import { Id } from '../../new_fields/FieldSymbols';
import { List } from '../../new_fields/List';
import { Cast, NumCast, StrCast } from '../../new_fields/Types';
@@ -9,6 +9,7 @@ import { DocumentView } from '../views/nodes/DocumentView';
import { LinkManager } from './LinkManager';
import { Scripting } from './Scripting';
import { SelectionManager } from './SelectionManager';
+import { DocumentType } from '../documents/DocumentTypes';
export class DocumentManager {
@@ -41,8 +42,8 @@ export class DocumentManager {
if (toReturn.length === 0) {
DocumentManager.Instance.DocumentViews.map(view => {
let doc = view.props.Document.proto;
- if (doc && doc[Id]) {
- if (doc[Id] === id) { toReturn.push(view); }
+ if (doc && doc[Id] && doc[Id] === id) {
+ toReturn.push(view);
}
});
}
@@ -72,6 +73,8 @@ export class DocumentManager {
toReturn = view;
}
});
+ } else {
+ break;
}
}
@@ -87,49 +90,40 @@ export class DocumentManager {
return views.length ? views[0] : undefined;
}
public getDocumentViews(toFind: Doc): DocumentView[] {
-
let toReturn: DocumentView[] = [];
- //gets document view that is in a freeform canvas collection
- DocumentManager.Instance.DocumentViews.map(view => {
- let doc = view.props.Document;
-
- if (doc === toFind) {
- toReturn.push(view);
- } else {
- if (Doc.AreProtosEqual(doc, toFind)) {
- toReturn.push(view);
- }
- }
- });
+ DocumentManager.Instance.DocumentViews.map(view =>
+ Doc.AreProtosEqual(view.props.Document, toFind) && toReturn.push(view));
return toReturn;
}
@computed
public get LinkedDocumentViews() {
- let pairs = DocumentManager.Instance.DocumentViews.filter(dv => dv.isSelected() || Doc.IsBrushed(dv.props.Document)).reduce((pairs, dv) => {
+ let pairs = DocumentManager.Instance.DocumentViews.filter(dv =>
+ (dv.isSelected() || Doc.IsBrushed(dv.props.Document)) // draw links from DocumentViews that are selected or brushed OR
+ || DocumentManager.Instance.DocumentViews.some(dv2 => { // Documentviews which
+ let rest = DocListCast(dv2.props.Document.links).some(l => Doc.AreProtosEqual(l, dv.props.Document));// are link doc anchors
+ let init = (dv2.isSelected() || Doc.IsBrushed(dv2.props.Document)) && dv2.Document.type !== DocumentType.AUDIO; // on a view that is selected or brushed
+ return init && rest;
+ })
+ ).reduce((pairs, dv) => {
let linksList = LinkManager.Instance.getAllRelatedLinks(dv.props.Document);
pairs.push(...linksList.reduce((pairs, link) => {
- if (link) {
- let linkToDoc = LinkManager.Instance.getOppositeAnchor(link, dv.props.Document);
- if (linkToDoc) {
- DocumentManager.Instance.getDocumentViews(linkToDoc).map(docView1 => {
- pairs.push({ a: dv, b: docView1, l: link });
- });
+ let linkToDoc = link && LinkManager.Instance.getOppositeAnchor(link, dv.props.Document);
+ linkToDoc && DocumentManager.Instance.getDocumentViews(linkToDoc).map(docView1 => {
+ if (dv.props.Document.type !== DocumentType.LINK || dv.props.layoutKey !== docView1.props.layoutKey) {
+ pairs.push({ a: dv, b: docView1, l: link });
}
- }
+ });
return pairs;
}, [] as { a: DocumentView, b: DocumentView, l: Doc }[]));
- // }
return pairs;
}, [] as { a: DocumentView, b: DocumentView, l: Doc }[]);
return pairs;
}
-
-
public jumpToDocument = async (targetDoc: Doc, willZoom: boolean, dockFunc?: (doc: Doc) => void, docContext?: Doc, linkId?: string, closeContextIfNotFound: boolean = false): Promise<void> => {
let highlight = () => {
const finalDocView = DocumentManager.Instance.getFirstDocumentView(targetDoc);
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 92666c03c..bbc29585c 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -14,6 +14,8 @@ import { ScriptField } from "../../new_fields/ScriptField";
import { List } from "../../new_fields/List";
import { PrefetchProxy } from "../../new_fields/Proxy";
import { listSpec } from "../../new_fields/Schema";
+import { Scripting } from "./Scripting";
+import { convertDropDataToButtons } from "./DropConverter";
export type dropActionType = "alias" | "copy" | undefined;
export function SetupDrag(
@@ -87,12 +89,12 @@ export async function DragLinkAsDocument(dragEle: HTMLElement, x: number, y: num
}
}
-export async function DragLinksAsDocuments(dragEle: HTMLElement, x: number, y: number, sourceDoc: Doc) {
+export async function DragLinksAsDocuments(dragEle: HTMLElement, x: number, y: number, sourceDoc: Doc, singleLink?: Doc) {
let srcTarg = sourceDoc.proto;
let draggedDocs: Doc[] = [];
if (srcTarg) {
- let linkDocs = LinkManager.Instance.getAllRelatedLinks(srcTarg);
+ let linkDocs = singleLink ? [singleLink] : LinkManager.Instance.getAllRelatedLinks(srcTarg);
if (linkDocs) {
draggedDocs = linkDocs.map(link => {
let opp = LinkManager.Instance.getOppositeAnchor(link, sourceDoc);
@@ -211,7 +213,9 @@ export namespace DragManager {
offset: number[];
dropAction: dropActionType;
userDropAction: dropActionType;
+ embedDoc?: boolean;
moveDocument?: MoveFunction;
+ isSelectionMove?: boolean; // indicates that an explicitly selected Document is being dragged. this will suppress onDragStart scripts
applyAsTemplate?: boolean;
[id: string]: any;
}
@@ -240,7 +244,7 @@ export namespace DragManager {
StartDrag(eles, dragData, downX, downY, options, options && options.finishDrag ? options.finishDrag :
(dropData: { [id: string]: any }) => {
(dropData.droppedDocuments =
- dragData.draggedDocuments.map(d => ScriptCast(d.onDragStart) ? ScriptCast(d.onDragStart).script.run({ this: d }).result :
+ dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? ScriptCast(d.onDragStart).script.run({ this: d }).result :
dragData.userDropAction === "alias" || (!dragData.userDropAction && dragData.dropAction === "alias") ? Doc.MakeAlias(d) :
dragData.userDropAction === "copy" || (!dragData.userDropAction && dragData.dropAction === "copy") ? Doc.MakeCopy(d, true) : d)
);
@@ -304,16 +308,6 @@ export namespace DragManager {
[id: string]: any;
}
- export class EmbedDragData {
- constructor(embeddableSourceDoc: Doc) {
- this.embeddableSourceDoc = embeddableSourceDoc;
- this.urlField = embeddableSourceDoc.data instanceof URLField ? embeddableSourceDoc.data : undefined;
- }
- embeddableSourceDoc: Doc;
- urlField?: URLField;
- [id: string]: any;
- }
-
// for column dragging in schema view
export class ColumnDragData {
constructor(colKey: SchemaHeaderField) {
@@ -327,10 +321,6 @@ export namespace DragManager {
StartDrag([ele], dragData, downX, downY, options);
}
- export function StartEmbedDrag(ele: HTMLElement, dragData: EmbedDragData, downX: number, downY: number, options?: DragOptions) {
- StartDrag([ele], dragData, downX, downY, options);
- }
-
export function StartColumnDrag(ele: HTMLElement, dragData: ColumnDragData, downX: number, downY: number, options?: DragOptions) {
StartDrag([ele], dragData, downX, downY, options);
}
@@ -426,7 +416,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 ? "alias" : undefined;
+ dragData.userDropAction = e.ctrlKey ? "alias" : undefined;
}
if (((options && !options.withoutShiftDrag) || !options) && e.shiftKey && CollectionDockingView.Instance) {
AbortDrag();
@@ -509,3 +499,4 @@ export namespace DragManager {
}
}
}
+Scripting.addGlobal(function convertToButtons(dragData: any) { convertDropDataToButtons(dragData as DragManager.DocumentDragData); });
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
new file mode 100644
index 000000000..6b53333d7
--- /dev/null
+++ b/src/client/util/DropConverter.ts
@@ -0,0 +1,46 @@
+import { DragManager } from "./DragManager";
+import { CollectionViewType } from "../views/collections/CollectionView";
+import { Doc, DocListCast } from "../../new_fields/Doc";
+import { DocumentType } from "../documents/DocumentTypes";
+import { ObjectField } from "../../new_fields/ObjectField";
+import { StrCast } from "../../new_fields/Types";
+import { Docs } from "../documents/Documents";
+import { ScriptField } from "../../new_fields/ScriptField";
+
+
+function makeTemplate(doc: Doc): boolean {
+ let layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc;
+ let layout = StrCast(layoutDoc.layout).match(/fieldKey={"[^"]*"}/)![0];
+ let fieldKey = layout.replace('fieldKey={"', "").replace(/"}$/, "");
+ let docs = DocListCast(layoutDoc[fieldKey]);
+ let any = false;
+ docs.map(d => {
+ if (!StrCast(d.title).startsWith("-")) {
+ any = true;
+ return Doc.MakeMetadataFieldTemplate(d, Doc.GetProto(layoutDoc));
+ }
+ if (d.type === DocumentType.COL) return makeTemplate(d);
+ return false;
+ });
+ return any;
+}
+export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
+ data && data.draggedDocuments.map((doc, i) => {
+ let dbox = doc;
+ if (!doc.onDragStart && !doc.onClick && doc.viewType !== CollectionViewType.Linear) {
+ let layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc;
+ if (layoutDoc.type === DocumentType.COL) {
+ layoutDoc.isTemplateDoc = makeTemplate(layoutDoc);
+ } else {
+ layoutDoc.isTemplateDoc = (layoutDoc.type === DocumentType.TEXT || layoutDoc.layout instanceof Doc) && !data.userDropAction;
+ }
+ dbox = Docs.Create.FontIconDocument({ nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, backgroundColor: StrCast(doc.backgroundColor), title: "Custom", icon: layoutDoc.isTemplateDoc ? "font" : "bolt" });
+ dbox.dragFactory = layoutDoc;
+ dbox.removeDropProperties = doc.removeDropProperties instanceof ObjectField ? ObjectField.MakeCopy(doc.removeDropProperties) : undefined;
+ dbox.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)');
+ } else if (doc.viewType === CollectionViewType.Linear) {
+ dbox.ignoreClick = true;
+ }
+ data.droppedDocuments[i] = dbox;
+ });
+}
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index d74b51993..f27d05487 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx
@@ -50,7 +50,7 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps>
@observable private uploading = false;
@observable private removeHover = false;
- public static LayoutString() { return FieldView.LayoutString(DirectoryImportBox); }
+ public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DirectoryImportBox, fieldKey); }
constructor(props: FieldViewProps) {
super(props);
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index 8a668e8d8..ee2f2dadc 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -1,10 +1,7 @@
-import { observable, action } from "mobx";
-import { StrCast, Cast, FieldValue } from "../../new_fields/Types";
import { Doc, DocListCast } from "../../new_fields/Doc";
-import { listSpec } from "../../new_fields/Schema";
import { List } from "../../new_fields/List";
-import { Id } from "../../new_fields/FieldSymbols";
-import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils";
+import { listSpec } from "../../new_fields/Schema";
+import { Cast, StrCast } from "../../new_fields/Types";
import { Docs } from "../documents/Documents";
import { Scripting } from "./Scripting";
@@ -79,7 +76,7 @@ export class LinkManager {
let related = LinkManager.Instance.getAllLinks().filter(link => {
let protomatch1 = Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, null));
let protomatch2 = Doc.AreProtosEqual(anchor, Cast(link.anchor2, Doc, null));
- return protomatch1 || protomatch2;
+ return protomatch1 || protomatch2 || Doc.AreProtosEqual(link, anchor);
});
return related;
}
@@ -242,11 +239,11 @@ export class LinkManager {
//TODO This should probably return undefined if there isn't an opposite anchor
//TODO This should also await the return value of the anchor so we don't filter out promises
public getOppositeAnchor(linkDoc: Doc, anchor: Doc): Doc | undefined {
- if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor1, Doc, null))) {
- return Cast(linkDoc.anchor2, Doc, null);
- } else {
- return Cast(linkDoc.anchor1, Doc, null);
- }
+ let a1 = Cast(linkDoc.anchor1, Doc, null);
+ let a2 = Cast(linkDoc.anchor2, Doc, null);
+ if (Doc.AreProtosEqual(anchor, a1)) return a2;
+ if (Doc.AreProtosEqual(anchor, a2)) return a1;
+ if (Doc.AreProtosEqual(anchor, linkDoc)) return linkDoc;
}
}
Scripting.addGlobal(function links(doc: any) {