aboutsummaryrefslogtreecommitdiff
path: root/src/new_fields
diff options
context:
space:
mode:
authorkimdahey <claire_kim1@brown.edu>2019-08-09 11:05:42 -0400
committerkimdahey <claire_kim1@brown.edu>2019-08-09 11:05:42 -0400
commitc407983788a09a5f93921439390834a4811b8842 (patch)
treeb757999bda24e13269608a6c63f116e55a702ba7 /src/new_fields
parent46637dc8f902077d613b737f576b755545a92c17 (diff)
parent68f613b5e762649b743059e494e9307eb103ff0d (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into tree_claire
Diffstat (limited to 'src/new_fields')
-rw-r--r--src/new_fields/Doc.ts84
-rw-r--r--src/new_fields/Types.ts8
-rw-r--r--src/new_fields/util.ts12
3 files changed, 85 insertions, 19 deletions
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index c01f4e8cf..87e048140 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -8,10 +8,10 @@ import { listSpec } from "./Schema";
import { ObjectField } from "./ObjectField";
import { RefField, FieldId } from "./RefField";
import { ToScriptString, SelfProxy, Parent, OnUpdate, Self, HandleUpdate, Update, Id } from "./FieldSymbols";
-import { scriptingGlobal } from "../client/util/Scripting";
+import { scriptingGlobal, CompileScript, Scripting } from "../client/util/Scripting";
import { List } from "./List";
import { DocumentType } from "../client/documents/Documents";
-import { ComputedField } from "./ScriptField";
+import { ComputedField, ScriptField } from "./ScriptField";
import { PrefetchProxy, ProxyField } from "./Proxy";
export namespace Field {
@@ -68,6 +68,7 @@ export function DocListCast(field: FieldResult): Doc[] {
export const WidthSym = Symbol("Width");
export const HeightSym = Symbol("Height");
+const CachedUpdates = Symbol("Cached updates");
function fetchProto(doc: Doc) {
const proto = doc.proto;
@@ -147,6 +148,8 @@ export class Doc extends RefField {
return "invalid";
}
+ private [CachedUpdates]: { [key: string]: () => void | Promise<any> } = {};
+
public async [HandleUpdate](diff: any) {
const set = diff.$set;
if (set) {
@@ -154,11 +157,18 @@ export class Doc extends RefField {
if (!key.startsWith("fields.")) {
continue;
}
- const value = await SerializationHelper.Deserialize(set[key]);
const fKey = key.substring(7);
- updatingFromServer = true;
- this[fKey] = value;
- updatingFromServer = false;
+ const fn = async () => {
+ const value = await SerializationHelper.Deserialize(set[key]);
+ updatingFromServer = true;
+ this[fKey] = value;
+ updatingFromServer = false;
+ };
+ if (DocServer.getFieldWriteMode(fKey)) {
+ this[CachedUpdates][fKey] = fn;
+ } else {
+ await fn();
+ }
}
}
const unset = diff.$unset;
@@ -168,9 +178,16 @@ export class Doc extends RefField {
continue;
}
const fKey = key.substring(7);
- updatingFromServer = true;
- delete this[fKey];
- updatingFromServer = false;
+ const fn = () => {
+ updatingFromServer = true;
+ delete this[fKey];
+ updatingFromServer = false;
+ };
+ if (DocServer.getFieldWriteMode(fKey)) {
+ this[CachedUpdates][fKey] = fn;
+ } else {
+ await fn();
+ }
}
}
}
@@ -187,6 +204,21 @@ export namespace Doc {
// return Cast(field, ctor);
// });
// }
+ export function RunCachedUpdate(doc: Doc, field: string) {
+ const update = doc[CachedUpdates][field];
+ if (update) {
+ update();
+ delete doc[CachedUpdates][field];
+ }
+ }
+ export function AddCachedUpdate(doc: Doc, field: string, oldValue: any) {
+ const val = oldValue;
+ doc[CachedUpdates][field] = () => {
+ updatingFromServer = true;
+ doc[field] = val;
+ updatingFromServer = false;
+ };
+ }
export function MakeReadOnly(): { end(): void } {
makeReadOnly();
return {
@@ -366,10 +398,15 @@ export namespace Doc {
}
}
export function MakeAlias(doc: Doc) {
- if (!GetT(doc, "isPrototype", "boolean", true)) {
- return Doc.MakeCopy(doc);
+ let alias = !GetT(doc, "isPrototype", "boolean", true) ? Doc.MakeCopy(doc) : Doc.MakeDelegate(doc);
+ let aliasNumber = Doc.GetProto(doc).aliasNumber = NumCast(Doc.GetProto(doc).aliasNumber) + 1;
+ let script = `return renameAlias(self, ${aliasNumber})`;
+ //let script = "StrCast(self.title).replace(/\\([0-9]*\\)/, \"\") + `(${n})`";
+ let compiled = CompileScript(script, { params: { this: "Doc" }, capturedVariables: { self: doc }, typecheck: false });
+ if (compiled.compiled) {
+ alias.title = new ComputedField(compiled);
}
- return Doc.MakeDelegate(doc); // bcz?
+ return alias;
}
//
@@ -542,4 +579,25 @@ export namespace Doc {
}
});
}
-} \ No newline at end of file
+
+ export class DocBrush {
+ @observable BrushedDoc: Doc[] = [];
+ }
+ const manager = new DocBrush();
+ export function IsBrushed(doc: Doc) {
+ return manager.BrushedDoc.some(d => Doc.AreProtosEqual(d, doc));
+ }
+ export function IsBrushedDegree(doc: Doc) {
+ return manager.BrushedDoc.some(d => d === doc) ? 2 : Doc.IsBrushed(doc) ? 1 : 0;
+ }
+ export function BrushDoc(doc: Doc) {
+ if (manager.BrushedDoc.indexOf(doc) === -1) runInAction(() => manager.BrushedDoc.push(doc));
+ }
+ export function UnBrushDoc(doc: Doc) {
+ let index = manager.BrushedDoc.indexOf(doc);
+ if (index !== -1) runInAction(() => manager.BrushedDoc.splice(index, 1));
+ }
+}
+Scripting.addGlobal(function renameAlias(doc: any, n: any) {
+ return StrCast(doc.title).replace(/\([0-9]*\)/, "") + `(${n})`;
+}); \ No newline at end of file
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index 565ae2ee3..09cbff25e 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -48,9 +48,11 @@ export interface Interface {
}
export type WithoutRefField<T extends Field> = T extends RefField ? never : T;
-export function Cast<T extends ToConstructor<Field> | ListSpec<Field>>(field: FieldResult, ctor: T): FieldResult<ToType<T>>;
-export function Cast<T extends ToConstructor<Field> | ListSpec<Field>>(field: FieldResult, ctor: T, defaultVal: WithoutList<WithoutRefField<ToType<T>>> | null): WithoutList<ToType<T>>;
-export function Cast<T extends ToConstructor<Field> | ListSpec<Field>>(field: FieldResult, ctor: T, defaultVal?: ToType<T> | null): FieldResult<ToType<T>> | undefined {
+export type CastCtor = ToConstructor<Field> | ListSpec<Field>;
+
+export function Cast<T extends CastCtor>(field: FieldResult, ctor: T): FieldResult<ToType<T>>;
+export function Cast<T extends CastCtor>(field: FieldResult, ctor: T, defaultVal: WithoutList<WithoutRefField<ToType<T>>> | null): WithoutList<ToType<T>>;
+export function Cast<T extends CastCtor>(field: FieldResult, ctor: T, defaultVal?: ToType<T> | null): FieldResult<ToType<T>> | undefined {
if (field instanceof Promise) {
return defaultVal === undefined ? field.then(f => Cast(f, ctor) as any) as any : defaultVal === null ? undefined : defaultVal;
}
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index c6f693f7f..6c05da507 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -6,7 +6,8 @@ import { RefField } from "./RefField";
import { ObjectField } from "./ObjectField";
import { action } from "mobx";
import { Parent, OnUpdate, Update, Id, SelfProxy, Self } from "./FieldSymbols";
-import { ComputedField } from "./ScriptField";
+import { DocServer } from "../client/DocServer";
+import { CurrentUserUtils } from "../server/authentication/models/current_user_utils";
function _readOnlySetter(): never {
throw new Error("Documents can't be modified in read-only mode");
@@ -63,9 +64,14 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number
} else {
target.__fields[prop] = value;
}
- if (value === undefined) target[Update]({ '$unset': { ["fields." + prop]: "" } });
+ const writeMode = DocServer.getFieldWriteMode(prop as string);
if (typeof value === "object" && !(value instanceof ObjectField)) debugger;
- else target[Update]({ '$set': { ["fields." + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) : (value === undefined ? null : value) } });
+ if (!writeMode || (writeMode === DocServer.WriteMode.SameUser && receiver.author === CurrentUserUtils.email)) {
+ if (value === undefined) target[Update]({ '$unset': { ["fields." + prop]: "" } });
+ else target[Update]({ '$set': { ["fields." + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) : (value === undefined ? null : value) } });
+ } else {
+ DocServer.registerDocWithCachedUpdate(receiver, prop as string, curValue);
+ }
UndoManager.AddEvent({
redo: () => receiver[prop] = value,
undo: () => receiver[prop] = curValue