diff options
Diffstat (limited to 'src/new_fields/Doc.ts')
-rw-r--r-- | src/new_fields/Doc.ts | 73 |
1 files changed, 44 insertions, 29 deletions
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 87e048140..d634cf57f 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -1,4 +1,4 @@ -import { observable, action, runInAction } from "mobx"; +import { observable, action, runInAction, ObservableMap } from "mobx"; import { serializable, primitive, map, alias, list, PropSchema, custom } from "serializr"; import { autoObject, SerializationHelper, Deserializable, afterDocDeserialize } from "../client/util/SerializationHelper"; import { DocServer } from "../client/DocServer"; @@ -7,12 +7,13 @@ import { Cast, ToConstructor, PromiseValue, FieldValue, NumCast, BoolCast, StrCa 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 { ToScriptString, SelfProxy, Parent, OnUpdate, Self, HandleUpdate, Update, Id, Copy } from "./FieldSymbols"; import { scriptingGlobal, CompileScript, Scripting } from "../client/util/Scripting"; import { List } from "./List"; import { DocumentType } from "../client/documents/Documents"; import { ComputedField, ScriptField } from "./ScriptField"; import { PrefetchProxy, ProxyField } from "./Proxy"; +import { CurrentUserUtils } from "../server/authentication/models/current_user_utils"; export namespace Field { export function toKeyValueString(doc: Doc, key: string): string { @@ -68,6 +69,7 @@ export function DocListCast(field: FieldResult): Doc[] { export const WidthSym = Symbol("Width"); export const HeightSym = Symbol("Height"); +export const UpdatingFromServer = Symbol("UpdatingFromServer"); const CachedUpdates = Symbol("Cached updates"); function fetchProto(doc: Doc) { @@ -77,8 +79,6 @@ function fetchProto(doc: Doc) { } } -let updatingFromServer = false; - @scriptingGlobal @Deserializable("Doc", fetchProto).withFields(["id"]) export class Doc extends RefField { @@ -132,8 +132,10 @@ export class Doc extends RefField { //{ [key: string]: Field | FieldWaiting | undefined } private ___fields: any = {}; + private [UpdatingFromServer]: boolean = false; + private [Update] = (diff: any) => { - if (updatingFromServer) { + if (this[UpdatingFromServer]) { return; } DocServer.UpdateField(this[Id], diff); @@ -152,6 +154,7 @@ export class Doc extends RefField { public async [HandleUpdate](diff: any) { const set = diff.$set; + const sameAuthor = this.author === CurrentUserUtils.email; if (set) { for (const key in set) { if (!key.startsWith("fields.")) { @@ -160,14 +163,15 @@ export class Doc extends RefField { const fKey = key.substring(7); const fn = async () => { const value = await SerializationHelper.Deserialize(set[key]); - updatingFromServer = true; + this[UpdatingFromServer] = true; this[fKey] = value; - updatingFromServer = false; + this[UpdatingFromServer] = false; }; - if (DocServer.getFieldWriteMode(fKey)) { - this[CachedUpdates][fKey] = fn; - } else { + if (sameAuthor || DocServer.getFieldWriteMode(fKey) !== DocServer.WriteMode.Playground) { + delete this[CachedUpdates][fKey]; await fn(); + } else { + this[CachedUpdates][fKey] = fn; } } } @@ -179,14 +183,15 @@ export class Doc extends RefField { } const fKey = key.substring(7); const fn = () => { - updatingFromServer = true; + this[UpdatingFromServer] = true; delete this[fKey]; - updatingFromServer = false; + this[UpdatingFromServer] = false; }; - if (DocServer.getFieldWriteMode(fKey)) { - this[CachedUpdates][fKey] = fn; - } else { + if (sameAuthor || DocServer.getFieldWriteMode(fKey) !== DocServer.WriteMode.Playground) { + delete this[CachedUpdates][fKey]; await fn(); + } else { + this[CachedUpdates][fKey] = fn; } } } @@ -214,9 +219,9 @@ export namespace Doc { export function AddCachedUpdate(doc: Doc, field: string, oldValue: any) { const val = oldValue; doc[CachedUpdates][field] = () => { - updatingFromServer = true; + doc[UpdatingFromServer] = true; doc[field] = val; - updatingFromServer = false; + doc[UpdatingFromServer] = false; }; } export function MakeReadOnly(): { end(): void } { @@ -305,6 +310,10 @@ export namespace Doc { export function GetProto(doc: Doc) { return Doc.GetT(doc, "isPrototype", "boolean", true) ? doc : (doc.proto || doc); } + export function GetDataDoc(doc: Doc): Doc { + let proto = Doc.GetProto(doc); + return proto === doc ? proto : Doc.GetDataDoc(proto); + } export function allKeys(doc: Doc): string[] { const results: Set<string> = new Set; @@ -379,7 +388,7 @@ export namespace Doc { docExtensionForField.extendsDoc = doc; // this is used by search to map field matches on the extension doc back to the document it extends. docExtensionForField.type = DocumentType.EXTENSION; let proto: Doc | undefined = doc; - while (proto && !Doc.IsPrototype(proto)) { + while (proto && !Doc.IsPrototype(proto) && proto.proto) { proto = proto.proto; } (proto ? proto : doc)[fieldKey + "_ext"] = new PrefetchProxy(docExtensionForField); @@ -450,7 +459,7 @@ export namespace Doc { export function GetLayoutDataDocPair(doc: Doc, dataDoc: Doc | undefined, fieldKey: string, childDocLayout: Doc) { let layoutDoc = childDocLayout; - let resolvedDataDoc = !doc.isTemplate && dataDoc !== doc ? dataDoc : undefined; + let resolvedDataDoc = !doc.isTemplate && dataDoc !== doc && dataDoc ? Doc.GetDataDoc(dataDoc) : undefined; if (resolvedDataDoc && Doc.WillExpandTemplateLayout(childDocLayout, resolvedDataDoc)) { Doc.UpdateDocumentExtensionForField(resolvedDataDoc, fieldKey); let fieldExtensionDoc = Doc.resolvedFieldDataDoc(resolvedDataDoc, StrCast(childDocLayout.templateField, StrCast(childDocLayout.title)), "dummy"); @@ -498,7 +507,8 @@ export namespace Doc { let _applyCount: number = 0; export function ApplyTemplate(templateDoc: Doc) { if (!templateDoc) return undefined; - let otherdoc = new Doc(); + let datadoc = new Doc(); + let otherdoc = Doc.MakeDelegate(datadoc); otherdoc.width = templateDoc[WidthSym](); otherdoc.height = templateDoc[HeightSym](); otherdoc.title = templateDoc.title + "(..." + _applyCount++ + ")"; @@ -506,6 +516,8 @@ export namespace Doc { otherdoc.miniLayout = StrCast(templateDoc.miniLayout); otherdoc.detailedLayout = otherdoc.layout; otherdoc.type = DocumentType.TEMPLATE; + !templateDoc.nativeWidth && (otherdoc.nativeWidth = 0); + !templateDoc.nativeHeight && (otherdoc.nativeHeight = 0); return otherdoc; } export function ApplyTemplateTo(templateDoc: Doc, target: Doc, targetData?: Doc) { @@ -514,6 +526,7 @@ export namespace Doc { target.nativeHeight = Doc.GetProto(target).nativeHeight = undefined; target.width = templateDoc.width; target.height = templateDoc.height; + target.onClick = templateDoc.onClick instanceof ObjectField && templateDoc.onClick[Copy](); Doc.GetProto(target).type = DocumentType.TEMPLATE; if (targetData && targetData.layout === target) { targetData.layout = temp; @@ -524,6 +537,8 @@ export namespace Doc { target.miniLayout = StrCast(templateDoc.miniLayout); target.detailedLayout = target.layout; } + !templateDoc.nativeWidth && (target.nativeWidth = 0); + !templateDoc.nativeHeight && (target.nativeHeight = 0); } export function MakeTemplate(fieldTemplate: Doc, metaKey: string, templateDataDoc: Doc) { @@ -581,23 +596,23 @@ export namespace Doc { } export class DocBrush { - @observable BrushedDoc: Doc[] = []; + @observable BrushedDoc: ObservableMap<Doc, boolean> = new ObservableMap(); } const manager = new DocBrush(); export function IsBrushed(doc: Doc) { - return manager.BrushedDoc.some(d => Doc.AreProtosEqual(d, doc)); + return manager.BrushedDoc.has(doc) || manager.BrushedDoc.has(Doc.GetDataDoc(doc)); } export function IsBrushedDegree(doc: Doc) { - return manager.BrushedDoc.some(d => d === doc) ? 2 : Doc.IsBrushed(doc) ? 1 : 0; + return manager.BrushedDoc.has(Doc.GetDataDoc(doc)) ? 2 : manager.BrushedDoc.has(doc) ? 1 : 0; } export function BrushDoc(doc: Doc) { - if (manager.BrushedDoc.indexOf(doc) === -1) runInAction(() => manager.BrushedDoc.push(doc)); + manager.BrushedDoc.set(doc, true); + manager.BrushedDoc.set(Doc.GetDataDoc(doc), true); } export function UnBrushDoc(doc: Doc) { - let index = manager.BrushedDoc.indexOf(doc); - if (index !== -1) runInAction(() => manager.BrushedDoc.splice(index, 1)); + manager.BrushedDoc.delete(doc); + manager.BrushedDoc.delete(Doc.GetDataDoc(doc)); } } -Scripting.addGlobal(function renameAlias(doc: any, n: any) { - return StrCast(doc.title).replace(/\([0-9]*\)/, "") + `(${n})`; -});
\ No newline at end of file +Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(doc.title).replace(/\([0-9]*\)/, "") + `(${n})`; }); +Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); });
\ No newline at end of file |