aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/LinkManager.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util/LinkManager.ts')
-rw-r--r--src/client/util/LinkManager.ts123
1 files changed, 62 insertions, 61 deletions
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index 2100b1195..d51cd350d 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -1,7 +1,6 @@
-import { validationResult } from "express-validator/check";
import { action, observable, observe } from "mobx";
import { computedFn } from "mobx-utils";
-import { DirectLinksSym, Doc, DocListCast, Field, Opt } from "../../fields/Doc";
+import { DirectLinksSym, Doc, DocListCast, DocListCastAsync, Field, Opt } from "../../fields/Doc";
import { List } from "../../fields/List";
import { ProxyField } from "../../fields/Proxy";
import { BoolCast, Cast, StrCast } from "../../fields/Types";
@@ -35,72 +34,74 @@ export class LinkManager {
constructor() {
LinkManager._instance = this;
this.createLinkrelationshipLists();
- setTimeout(() => {
- LinkManager.userLinkDBs = [];
- const addLinkToDoc = (link: Doc) => {
- const a1Prom = link?.anchor1;
- const a2Prom = link?.anchor2;
- Promise.all([a1Prom, a2Prom]).then((all) => {
- const a1 = all[0];
- const a2 = all[1];
- const a1ProtoProm = (link?.anchor1 as Doc)?.proto;
- const a2ProtoProm = (link?.anchor2 as Doc)?.proto;
- Promise.all([a1ProtoProm, a2ProtoProm]).then(action((all) => {
- if (a1 instanceof Doc && a2 instanceof Doc && ((a1.author !== undefined && a2.author !== undefined) || link.author === Doc.CurrentUserEmail)) {
- Doc.GetProto(a1)[DirectLinksSym].add(link);
- Doc.GetProto(a2)[DirectLinksSym].add(link);
- Doc.GetProto(link)[DirectLinksSym].add(link);
- }
- }));
- });
- };
- const remLinkFromDoc = (link: Doc) => {
- const a1 = link?.anchor1;
- const a2 = link?.anchor2;
- Promise.all([a1, a2]).then(action(() => {
+ LinkManager.userLinkDBs = [];
+ const addLinkToDoc = (link: Doc) => {
+ const a1Prom = link?.anchor1;
+ const a2Prom = link?.anchor2;
+ Promise.all([a1Prom, a2Prom]).then((all) => {
+ const a1 = all[0];
+ const a2 = all[1];
+ const a1ProtoProm = (link?.anchor1 as Doc)?.proto;
+ const a2ProtoProm = (link?.anchor2 as Doc)?.proto;
+ Promise.all([a1ProtoProm, a2ProtoProm]).then(action((all) => {
if (a1 instanceof Doc && a2 instanceof Doc && ((a1.author !== undefined && a2.author !== undefined) || link.author === Doc.CurrentUserEmail)) {
- Doc.GetProto(a1)[DirectLinksSym].delete(link);
- Doc.GetProto(a2)[DirectLinksSym].delete(link);
- Doc.GetProto(link)[DirectLinksSym].delete(link);
+ Doc.GetProto(a1)[DirectLinksSym].add(link);
+ Doc.GetProto(a2)[DirectLinksSym].add(link);
+ Doc.GetProto(link)[DirectLinksSym].add(link);
}
}));
- };
- const watchUserLinkDB = (userLinkDBDoc: Doc) => {
- LinkManager.links.push(...DocListCast(userLinkDBDoc.data));
- const toRealField = (field: Field) => field instanceof ProxyField ? field.value() : field; // see List.ts. data structure is not a simple list of Docs, but a list of ProxyField/Fields
- observe(userLinkDBDoc.data as Doc, change => { // observe pushes/splices on a user link DB 'data' field (should only happen for local changes)
- switch (change.type as any) {
- case "splice":
- (change as any).added.forEach((link: any) => addLinkToDoc(toRealField(link)));
- (change as any).removed.forEach((link: any) => remLinkFromDoc(toRealField(link)));
- break;
- case "update": //let oldValue = change.oldValue;
- }
- }, true);
- observe(userLinkDBDoc, "data", // obsever when a new array of links is assigned as the link DB 'data' field (should happen whenever a remote user adds/removes a link)
- change => {
- switch (change.type as any) {
- case "update":
- Promise.all([...(change.oldValue as any as Doc[] || []), ...(change.newValue as any as Doc[] || [])]).then(doclist => {
- const oldDocs = doclist.slice(0, (change.oldValue as any as Doc[] || []).length);
- const newDocs = doclist.slice((change.oldValue as any as Doc[] || []).length, doclist.length);
-
- const added = newDocs?.filter(link => !(oldDocs || []).includes(link));
- const removed = oldDocs?.filter(link => !(newDocs || []).includes(link));
- added?.forEach((link: any) => addLinkToDoc(toRealField(link)));
- removed?.forEach((link: any) => remLinkFromDoc(toRealField(link)));
- });
- }
- }, true);
- };
- observe(LinkManager.userLinkDBs, change => {
+ });
+ };
+ const remLinkFromDoc = (link: Doc) => {
+ const a1 = link?.anchor1;
+ const a2 = link?.anchor2;
+ Promise.all([a1, a2]).then(action(() => {
+ if (a1 instanceof Doc && a2 instanceof Doc && ((a1.author !== undefined && a2.author !== undefined) || link.author === Doc.CurrentUserEmail)) {
+ Doc.GetProto(a1)[DirectLinksSym].delete(link);
+ Doc.GetProto(a2)[DirectLinksSym].delete(link);
+ Doc.GetProto(link)[DirectLinksSym].delete(link);
+ }
+ }));
+ };
+ const watchUserLinkDB = (userLinkDBDoc: Doc) => {
+ LinkManager.links.push(...DocListCast(userLinkDBDoc.data));
+ const toRealField = (field: Field) => field instanceof ProxyField ? field.value() : field; // see List.ts. data structure is not a simple list of Docs, but a list of ProxyField/Fields
+ observe(userLinkDBDoc.data as Doc, change => { // observe pushes/splices on a user link DB 'data' field (should only happen for local changes)
switch (change.type as any) {
- case "splice": (change as any).added.forEach(watchUserLinkDB); break;
+ case "splice":
+ (change as any).added.forEach((link: any) => addLinkToDoc(toRealField(link)));
+ (change as any).removed.forEach((link: any) => remLinkFromDoc(toRealField(link)));
+ break;
case "update": //let oldValue = change.oldValue;
}
}, true);
- LinkManager.addLinkDB(Doc.LinkDBDoc());
- });
+ observe(userLinkDBDoc, "data", // obsever when a new array of links is assigned as the link DB 'data' field (should happen whenever a remote user adds/removes a link)
+ change => {
+ switch (change.type as any) {
+ case "update":
+ Promise.all([...(change.oldValue as any as Doc[] || []), ...(change.newValue as any as Doc[] || [])]).then(doclist => {
+ const oldDocs = doclist.slice(0, (change.oldValue as any as Doc[] || []).length);
+ const newDocs = doclist.slice((change.oldValue as any as Doc[] || []).length, doclist.length);
+
+ const added = newDocs?.filter(link => !(oldDocs || []).includes(link));
+ const removed = oldDocs?.filter(link => !(newDocs || []).includes(link));
+ added?.forEach((link: any) => addLinkToDoc(toRealField(link)));
+ removed?.forEach((link: any) => remLinkFromDoc(toRealField(link)));
+ });
+ }
+ }, true);
+ };
+ observe(LinkManager.userLinkDBs, change => {
+ switch (change.type as any) {
+ case "splice": (change as any).added.forEach(watchUserLinkDB); break;
+ case "update": //let oldValue = change.oldValue;
+ }
+ }, true);
+ LinkManager.addLinkDB(Doc.LinkDBDoc());
+ DocListCastAsync(Doc.LinkDBDoc()?.data).then(dblist => dblist?.forEach(async link => { // make sure anchors are loaded to avoid incremental updates to computedFn's in LinkManager
+ const a1 = await Cast(link?.anchor1, Doc, null);
+ const a2 = await Cast(link?.anchor2, Doc, null);
+ }));
}