diff options
Diffstat (limited to 'src/new_fields')
-rw-r--r-- | src/new_fields/Doc.ts | 38 | ||||
-rw-r--r-- | src/new_fields/util.ts | 11 |
2 files changed, 40 insertions, 9 deletions
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index b3d1dc109..736e8e69d 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -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]: () => 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 = async () => { + updatingFromServer = true; + delete this[fKey]; + updatingFromServer = false; + }; + if (DocServer.getFieldWriteMode(fKey)) { + this[CachedUpdates][fKey] = fn; + } else { + await fn(); + } } } } @@ -187,6 +204,13 @@ 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 MakeReadOnly(): { end(): void } { makeReadOnly(); return { diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts index 48ae9f216..099fe2d0a 100644 --- a/src/new_fields/util.ts +++ b/src/new_fields/util.ts @@ -6,6 +6,8 @@ import { RefField } from "./RefField"; import { ObjectField } from "./ObjectField"; import { action } from "mobx"; import { Parent, OnUpdate, Update, Id, SelfProxy, Self } from "./FieldSymbols"; +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"); @@ -62,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); + } UndoManager.AddEvent({ redo: () => receiver[prop] = value, undo: () => receiver[prop] = curValue |