From 5816840af60f97a34318a52a5276482cab392496 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 16 Oct 2020 15:48:54 -0400 Subject: updated user initialization code to not generate server traffic when creating a new account. set user accounts to update their cache 2.5s after login. --- src/client/util/CurrentUserUtils.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index dcbeba8cd..f43b6df44 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -878,7 +878,7 @@ export class CurrentUserUtils { // Sharing sidebar is where shared documents are contained static async setupSharingSidebar(doc: Doc, sharingDocumentId: string, linkDatabaseId: string) { if (doc.myLinkDatabase === undefined) { - let linkDocs = await DocServer.GetRefField(linkDatabaseId); + let linkDocs = Docs.newAccount ? undefined : await DocServer.GetRefField(linkDatabaseId); if (!linkDocs) { linkDocs = new Doc(linkDatabaseId, true); (linkDocs as Doc).author = Doc.CurrentUserEmail; @@ -888,7 +888,7 @@ export class CurrentUserUtils { doc.myLinkDatabase = new PrefetchProxy(linkDocs); } if (doc.mySharedDocs === undefined) { - let sharedDocs = await DocServer.GetRefField(sharingDocumentId + "outer"); + let sharedDocs = Docs.newAccount ? undefined : await DocServer.GetRefField(sharingDocumentId + "outer"); if (!sharedDocs) { sharedDocs = Docs.Create.StackingDocument([], { title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "none", childLimitHeight: 0, _yMargin: 50, _gridGap: 15, @@ -1024,6 +1024,7 @@ export class CurrentUserUtils { // Doc.AddDocToList(Cast(doc["template-notes"], Doc, null), "data", deleg); // } // }); + setTimeout(() => DocServer.UPDATE_SERVER_CACHE(), 2500); return doc; } @@ -1047,8 +1048,12 @@ export class CurrentUserUtils { await rp.get(Utils.prepend("/getUserDocumentIds")).then(ids => { const { userDocumentId, sharingDocumentId, linkDatabaseId } = JSON.parse(ids); if (userDocumentId !== "guest") { - return DocServer.GetRefField(userDocumentId).then(async field => - this.updateUserDocument(Doc.SetUserDoc(field instanceof Doc ? field : new Doc(userDocumentId, true)), sharingDocumentId, linkDatabaseId)); + return DocServer.GetRefField(userDocumentId).then(async field => { + Docs.newAccount = !(field instanceof Doc); + await Docs.Prototypes.initialize(); + const userDoc = Docs.newAccount ? new Doc(userDocumentId, true) : field as Doc; + return this.updateUserDocument(Doc.SetUserDoc(userDoc), sharingDocumentId, linkDatabaseId); + }); } else { throw new Error("There should be a user id! Why does Dash think there isn't one?"); } @@ -1108,7 +1113,7 @@ export class CurrentUserUtils { const response = await fetch(upload, { method: "POST", body: formData }); const json = await response.json(); if (json !== "error") { - const doc = await DocServer.GetRefField(json); + const doc = Docs.newAccount ? undefined : await DocServer.GetRefField(json); if (doc instanceof Doc) { setTimeout(() => SearchUtil.Search(`{!join from=id to=proto_i}id:link*`, true, {}).then(docs => docs.docs.forEach(d => LinkManager.Instance.addLink(d))), 2000); // need to give solr some time to update so that this query will find any link docs we've added. -- cgit v1.2.3-70-g09d2 From 6cfd2a37494bf531c88e26ea89b5b776805d31a8 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 20 Oct 2020 23:36:45 -0400 Subject: fixes for overlayDocs for undo/redo in presBox - undo/redo of minimize/show sidebar. --- src/client/util/CurrentUserUtils.ts | 1 + src/client/views/OverlayView.tsx | 9 ++------- .../collectionFreeForm/CollectionFreeFormView.tsx | 5 +++-- src/client/views/nodes/DocumentView.tsx | 8 ++++---- src/client/views/nodes/PresBox.tsx | 19 +++++++++---------- src/fields/documentSchemas.ts | 1 - 6 files changed, 19 insertions(+), 24 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index f43b6df44..38bfe3fb6 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1190,6 +1190,7 @@ export class CurrentUserUtils { public static get MyRecentlyClosed() { return Cast(Doc.UserDoc().myRecentlyClosedDocs, Doc, null); } public static get MyDashboards() { return Cast(Doc.UserDoc().myDashboards, Doc, null); } public static get EmptyPane() { return Cast(Doc.UserDoc().emptyPane, Doc, null); } + public static get OverlayDocs() { return DocListCast((Doc.UserDoc().myOverlayDocs as Doc)?.data); } } Scripting.addGlobal(function openDragFactory(dragFactory: Doc) { diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx index b40c9edfb..7d47abdce 100644 --- a/src/client/views/OverlayView.tsx +++ b/src/client/views/OverlayView.tsx @@ -14,6 +14,7 @@ import { Scripting } from "../util/Scripting"; import { ScriptingRepl } from './ScriptingRepl'; import { DragManager } from "../util/DragManager"; import { List } from "../../fields/List"; +import { CurrentUserUtils } from "../util/CurrentUserUtils"; export type OverlayDisposer = () => void; @@ -146,12 +147,7 @@ export class OverlayView extends React.Component { @computed get overlayDocs() { - const userDocOverlays = Doc.UserDoc().myOverlayDocs; - if (!userDocOverlays) { - return null; - } - return userDocOverlays instanceof Doc && DocListCast(userDocOverlays.data).map(d => { - setTimeout(() => d.inOverlay = true, 0); + return CurrentUserUtils.OverlayDocs?.map(d => { let offsetx = 0, offsety = 0; const dref = React.createRef(); const onPointerMove = action((e: PointerEvent, down: number[]) => { @@ -161,7 +157,6 @@ export class OverlayView extends React.Component { } if (e.metaKey) { const dragData = new DragManager.DocumentDragData([d]); - d.removeDropProperties = new List(["inOverlay"]); dragData.offset = [-offsetx, -offsety]; dragData.dropAction = "move"; dragData.removeDocument = (doc: Doc | Doc[]) => { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 56624f42d..fdcfb00d8 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -46,6 +46,7 @@ import "./CollectionFreeFormView.scss"; import { MarqueeOptionsMenu } from "./MarqueeOptionsMenu"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); +import { CurrentUserUtils } from "../../../util/CurrentUserUtils"; export const panZoomSchema = createSchema({ _panX: "number", @@ -803,7 +804,7 @@ export class CollectionFreeFormView extends CollectionSubView { - if (this.layoutDoc._lockedTransform || this.props.Document.inOverlay || this.props.Document.treeViewOutlineMode) return; + if (this.layoutDoc._lockedTransform || CurrentUserUtils.OverlayDocs.includes(this.props.Document) || this.props.Document.treeViewOutlineMode) return; if (!e.ctrlKey && this.props.Document.scrollHeight !== undefined) { // things that can scroll vertically should do that instead of zooming e.stopPropagation(); } @@ -839,7 +840,7 @@ export class CollectionFreeFormView extends CollectionSubView(Docu this._downX = touch.clientX; this._downY = touch.clientY; if (!e.nativeEvent.cancelBubble) { - if ((this.active || this.layoutDoc.onDragStart || this.onClickHandler) && !e.ctrlKey && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) e.stopPropagation(); + if ((this.active || this.layoutDoc.onDragStart || this.onClickHandler) && !e.ctrlKey && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) e.stopPropagation(); this.removeMoveListeners(); this.addMoveListeners(); this.removeEndListeners(); @@ -438,7 +438,7 @@ export class DocumentView extends DocComponent(Docu if (e.cancelBubble && this.active) { this.removeMoveListeners(); } - else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.onClickHandler) && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) { + else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.onClickHandler) && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { const touch = me.touchEvent.changedTouches.item(0); if (touch && (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3)) { @@ -554,7 +554,7 @@ export class DocumentView extends DocComponent(Docu if ((this.active || this.layoutDoc.onDragStart) && !e.ctrlKey && (e.button === 0 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) && - !this.layoutDoc.inOverlay) { + !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { e.stopPropagation(); if (SelectionManager.IsSelected(this, true) && this.layoutDoc._viewType !== CollectionViewType.Docking) e.preventDefault(); // goldenlayout needs to be able to move its tabs, so can't preventDefault for it } @@ -573,7 +573,7 @@ export class DocumentView extends DocComponent(Docu if (e.cancelBubble && this.active) { document.removeEventListener("pointermove", this.onPointerMove); // stop listening to pointerMove if something else has stopPropagated it (e.g., the MarqueeView) } - else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart) && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) { + else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart) && !this.layoutDoc.lockedPosition && !CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler) && (e.buttons === 1 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE))) { document.removeEventListener("pointermove", this.onPointerMove); diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 53b2433e8..9723937a7 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -520,11 +520,10 @@ export class PresBox extends ViewBoxBaseComponent @action updateMinimize = () => { const docView = DocumentManager.Instance.getDocumentView(this.layoutDoc); - if (this.layoutDoc.inOverlay) { + if (CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { this.layoutDoc.presStatus = PresStatus.Edit; Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocs as Doc), undefined, this.rootDoc); CollectionDockingView.AddSplit(this.rootDoc, "right"); - this.layoutDoc.inOverlay = false; } else if (this.layoutDoc.context && docView) { this.layoutDoc.presStatus = PresStatus.Edit; clearTimeout(this._presTimer); @@ -716,7 +715,7 @@ export class PresBox extends ViewBoxBaseComponent const anchorNode = document.activeElement as HTMLDivElement; if (anchorNode && anchorNode.className?.includes("lm_title")) return; if (e.keyCode === 27) { // Escape key - if (this.layoutDoc.inOverlay) { this.updateMinimize(); } + if (CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { this.updateMinimize(); } else if (this.layoutDoc.presStatus === "edit") { this._selectedArray = []; this._eleArray = []; this._dragArray = []; } else this.layoutDoc.presStatus = "edit"; if (this._presTimer) clearTimeout(this._presTimer); @@ -1360,10 +1359,10 @@ export class PresBox extends ViewBoxBaseComponent @computed get presentDropdown() { return (
e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}> -
{ this.updateMinimize(); this.turnOffEdit(true); }))}> +
{ this.updateMinimize(); this.turnOffEdit(true); })))}> Minimize
-
{ this.layoutDoc.presStatus = "manual"; this.turnOffEdit(true); }))}> +
{ this.layoutDoc.presStatus = "manual"; this.turnOffEdit(true); })))}> Sidebar view
@@ -1949,8 +1948,8 @@ export class PresBox extends ViewBoxBaseComponent {this.playButtonFrames}
- {this.props.PanelWidth() > 250 ?
{ this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }}>EXIT
- :
this.layoutDoc.presStatus = "edit"}> + {this.props.PanelWidth() > 250 ?
{ this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }))}>EXIT
+ :
this.layoutDoc.presStatus = "edit"))}>
}
); @@ -1968,7 +1967,7 @@ export class PresBox extends ViewBoxBaseComponent // needed to ensure that the childDocs are loaded for looking up fields this.childDocs.slice(); const mode = StrCast(this.rootDoc._viewType) as CollectionViewType; - return this.layoutDoc.inOverlay ? + return CurrentUserUtils.OverlayDocs.includes(this.rootDoc) ?
{"Loop"}
}>
this.layoutDoc.presLoop = !this.layoutDoc.presLoop}>
@@ -1982,11 +1981,11 @@ export class PresBox extends ViewBoxBaseComponent {this.playButtonFrames}
-
{ this.updateMinimize(); this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }}>EXIT
+
{ this.updateMinimize(); this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }))}>EXIT
: -
+
{this.topPanel} {this.toolbar} {this.newDocumentToolbarDropdown} diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index 71294c59c..311aaa769 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -19,7 +19,6 @@ export const documentSchema = createSchema({ activeFrame: "number", // the active frame of a frame based animated document _currentTimecode: "number", // current play back time of a temporal document (video / audio) displayTimecode: "number", // the time that a document should be displayed (e.g., time an annotation should be displayed on a video) - inOverlay: "boolean", // whether the document is rendered in an OverlayView which handles selection/dragging differently isLabel: "boolean", // whether the document is a label or not (video / audio) audioStart: "number", // the time frame where the audio should begin playing audioEnd: "number", // the time frame where the audio should stop playing -- cgit v1.2.3-70-g09d2 From 040d65234f52dc3337483acdb2c1c6d0cc8fefa2 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Oct 2020 13:30:01 -0400 Subject: added alert for uknown filetype uploads --- src/client/util/CurrentUserUtils.ts | 3 +++ src/client/views/collections/CollectionSubView.tsx | 2 ++ 2 files changed, 5 insertions(+) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 38bfe3fb6..07447b93c 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1124,6 +1124,9 @@ export class CurrentUserUtils { const disposer = OverlayView.ShowSpinner(); DocListCastAsync(importDocs.data).then(async list => { const results = await DocUtils.uploadFilesToDocs(Array.from(input.files || []), {}); + if (results.length !== input.files?.length) { + alert("Error uploading files - possibly due to unsupported file types") + } list?.splice(0, 0, ...results); disposer(); }); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 5c3c70be2..0dd033e47 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -482,6 +482,8 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: } else { if (text && !text.includes("https://")) { UndoManager.RunInBatch(() => this.addDocument(Docs.Create.TextDocument(text, { ...options, title: text.substring(0, 20), _width: 400, _height: 315 })), "drop"); + } else { + alert("Document updloaded failed - possibly an unsupported file type.") } } disposer(); -- cgit v1.2.3-70-g09d2 From 749873972fba8ed8d5b34b73b43947d6356b882e Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 22 Oct 2020 22:23:39 -0400 Subject: added more caching for linkManager queries. --- src/client/util/CurrentUserUtils.ts | 4 +- src/client/util/LinkManager.ts | 106 ++++++--------------- src/client/views/collections/CollectionMenu.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 2 +- src/client/views/collections/TabDocView.tsx | 2 +- 5 files changed, 33 insertions(+), 83 deletions(-) (limited to 'src/client/util/CurrentUserUtils.ts') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 07447b93c..5886aa13f 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -1125,7 +1125,7 @@ export class CurrentUserUtils { DocListCastAsync(importDocs.data).then(async list => { const results = await DocUtils.uploadFilesToDocs(Array.from(input.files || []), {}); if (results.length !== input.files?.length) { - alert("Error uploading files - possibly due to unsupported file types") + alert("Error uploading files - possibly due to unsupported file types"); } list?.splice(0, 0, ...results); disposer(); @@ -1212,7 +1212,5 @@ Scripting.addGlobal(function createNewPresentation() { return MainView.Instance. "creates a new presentation when called"); Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); }, "returns all the links to the document or its annotations", "(doc: any)"); -Scripting.addGlobal(function directLinks(doc: any) { return new List(LinkManager.Instance.getAllDirectLinks(doc)); }, - "returns all the links directly to the document", "(doc: any)"); Scripting.addGlobal(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar"); diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 1ba6cff6d..c3ab7c6e7 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -25,94 +25,52 @@ export class LinkManager { public static currentLink: Opt; - public static get Instance(): LinkManager { - return this._instance || (this._instance = new this()); - } - - private constructor() { - } - + public static get Instance(): LinkManager { return this._instance || (this._instance = new this()); } - public getAllLinks(): Doc[] { - const lset = new Set(DocListCast(Doc.LinkDBDoc().data)); - SharingManager.Instance.users.forEach(user => { - DocListCast(user.linkDatabase?.data).map(doc => { - lset.add(doc); - }); - }); - return Array.from(lset); - } + public addLink(linkDoc: Doc) { return Doc.AddDocToList(Doc.LinkDBDoc(), "data", linkDoc); } - public addLink(linkDoc: Doc): boolean { - return Doc.AddDocToList(Doc.LinkDBDoc(), "data", linkDoc); - } + public deleteLink(linkDoc: Doc) { return Doc.RemoveDocFromList(Doc.LinkDBDoc(), "data", linkDoc); } - public deleteLink(linkDoc: Doc): boolean { - return Doc.RemoveDocFromList(Doc.LinkDBDoc(), "data", linkDoc); - } + public deleteAllLinksOnAnchor(anchor: Doc) { LinkManager.Instance.getAllRelatedLinks(anchor).forEach(linkDoc => LinkManager.Instance.deleteLink(linkDoc)); } - // finds all links that contain the given anchor - public getAllDirectLinks(anchor: Doc): Doc[] { - const related = LinkManager.Instance.getAllLinks().filter(link => link).filter(link => { - const a1 = Cast(link.anchor1, Doc, null); - const a2 = Cast(link.anchor2, Doc, null); - const protomatch1 = Doc.AreProtosEqual(anchor, a1); - const protomatch2 = Doc.AreProtosEqual(anchor, a2); - return ((a1?.author !== undefined && a2?.author !== undefined) || link.author === Doc.CurrentUserEmail) && (protomatch1 || protomatch2 || Doc.AreProtosEqual(link, anchor)); - }); - return related; - } + public getAllRelatedLinks(anchor: Doc) { return this.relatedLinker(anchor); } // finds all links that contain the given anchor - relatedLinker = computedFn(function realtedLinker(this: any, anchor: Doc) { - const related = LinkManager.Instance.getAllDirectLinks(anchor); - DocListCast(anchor[Doc.LayoutFieldKey(anchor) + "-annotations"]).map(anno => { - related.push(...LinkManager.Instance.getAllRelatedLinks(anno)); - }); - return related; - }.bind(this), true); + public getAllDirectLinks(anchor: Doc): Doc[] { return this.directLinker(anchor); } // finds all links that contain the given anchor - // finds all links that contain the given anchor - public getAllRelatedLinks(anchor: Doc): Doc[] { - return this.relatedLinker(anchor); - } + public getAllLinks(): Doc[] { return this.allLinks(); } - public deleteAllLinksOnAnchor(anchor: Doc) { - const related = LinkManager.Instance.getAllRelatedLinks(anchor); - related.forEach(linkDoc => LinkManager.Instance.deleteLink(linkDoc)); - } + allLinks = computedFn(function allLinks(this: any) { + const lset = new Set(DocListCast(Doc.LinkDBDoc().data)); + SharingManager.Instance.users.forEach(user => DocListCast(user.linkDatabase?.data).map(doc => lset.add(doc))); + return Array.from(lset); + }, true); - // gets the groups associates with an anchor in a link - public getAnchorGroups(linkDoc: Doc, anchor?: Doc): Array { - if (Doc.AreProtosEqual(anchor, Cast(linkDoc.anchor1, Doc, null))) { - return DocListCast(linkDoc.anchor1Groups); - } else { - return DocListCast(linkDoc.anchor2Groups); - } - } - public addGroupToAnchor(linkDoc: Doc, anchor: Doc, groupDoc: Doc, replace: boolean = false) { - Doc.GetProto(linkDoc).linkRelationship = groupDoc.linkRelationship; - } + directLinker = computedFn(function directLinker(this: any, anchor: Doc) { + return LinkManager.Instance.getAllLinks().filter(link => { + const a1 = Cast(link?.anchor1, Doc, null); + const a2 = Cast(link?.anchor2, Doc, null); + return link && ((a1?.author !== undefined && a2?.author !== undefined) || link.author === Doc.CurrentUserEmail) && (Doc.AreProtosEqual(anchor, a1) || Doc.AreProtosEqual(anchor, a2) || Doc.AreProtosEqual(link, anchor)); + }); + }, true); - // removes group doc of given group type only from given anchor on given link - public removeGroupFromAnchor(linkDoc: Doc, anchor: Doc, groupType: string) { - Doc.GetProto(linkDoc).linkRelationship = "-ungrouped-"; - } + relatedLinker = computedFn(function relatedLinker(this: any, anchor: Doc) { + const related = LinkManager.Instance.directLinker(anchor); + DocListCast(anchor[Doc.LayoutFieldKey(anchor) + "-annotations"]).map(anno => related.push(...LinkManager.Instance.getAllRelatedLinks(anno))); + return related; + }, true); // returns map of group type to anchor's links in that group type public getRelatedGroupedLinks(anchor: Doc): Map> { - const related = this.getAllRelatedLinks(anchor); const anchorGroups = new Map>(); - related.forEach(link => { + this.getAllRelatedLinks(anchor).forEach(link => { if (!link.linkRelationship || link?.linkRelationship !== "-ungrouped-") { const group = anchorGroups.get(StrCast(link.linkRelationship)); anchorGroups.set(StrCast(link.linkRelationship), group ? [...group, link] : [link]); - } else { // if link is in no groups then put it in default group const group = anchorGroups.get("*"); anchorGroups.set("*", group ? [...group, link] : [link]); } - }); return anchorGroups; } @@ -120,21 +78,15 @@ export class LinkManager { // returns a list of all metadata docs associated with the given group type public getAllMetadataDocsInGroup(groupType: string): Array { const md: Doc[] = []; - const allLinks = LinkManager.Instance.getAllLinks(); - allLinks.forEach(linkDoc => { - if (StrCast(linkDoc.linkRelationship).toUpperCase() === groupType.toUpperCase()) { md.push(linkDoc); } - }); + LinkManager.Instance.getAllLinks().forEach(linkDoc => StrCast(linkDoc.linkRelationship).toUpperCase() === groupType.toUpperCase() && md.push(linkDoc)); return md; } // checks if a link with the given anchors exists public doesLinkExist(anchor1: Doc, anchor2: Doc): boolean { - const allLinks = LinkManager.Instance.getAllLinks(); - const index = allLinks.findIndex(linkDoc => { - return (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor1) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor2)) || - (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor2) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor1)); - }); - return index !== -1; + return -1 !== LinkManager.Instance.getAllLinks().findIndex(linkDoc => + (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor1) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor2)) || + (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor2) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor1))); } // finds the opposite anchor of a given anchor in a link diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index fed9be062..abad23e0d 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -429,7 +429,7 @@ export class CollectionViewBaseChrome extends React.Component; const targetDoc = this.selectedDoc; {/* return (!targetDoc || (targetDoc._viewType !== CollectionViewType.Freeform && targetDoc.type !== DocumentType.IMG)) ? (null) :
{"Pin to presentation trail with current view"}
} placement="top"> */ } - return (targetDoc && targetDoc.type !== DocumentType.PRES && (targetDoc._viewType === CollectionViewType.Freeform || targetDoc._viewType === CollectionViewType.Stacking || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.VIDEO || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.COMPARISON)) ?
{"Pin to presentation trail with current view"}
} placement="top"> + return (targetDoc && targetDoc.type !== DocumentType.PRES && (targetDoc._viewType === CollectionViewType.Freeform || targetDoc._viewType === CollectionViewType.Stacking || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.VID || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.COMPARISON)) ?
{"Pin to presentation trail with current view"}
} placement="top">