diff options
Diffstat (limited to 'src/fields/util.ts')
-rw-r--r-- | src/fields/util.ts | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/src/fields/util.ts b/src/fields/util.ts index 4da9fce74..8a694de83 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -11,7 +11,7 @@ import { ComputedField } from "./ScriptField"; import { ScriptCast, StrCast } from "./Types"; import { returnZero } from "../Utils"; import CursorField from "./CursorField"; - +import { List } from "./List"; function _readOnlySetter(): never { throw new Error("Documents can't be modified in read-only mode"); @@ -93,7 +93,7 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number } else { DocServer.registerDocWithCachedUpdate(receiver, prop as string, curValue); } - UndoManager.AddEvent({ + !receiver[UpdatingFromServer] && UndoManager.AddEvent({ redo: () => receiver[prop] = value, undo: () => receiver[prop] = curValue }); @@ -371,18 +371,44 @@ export function deleteProperty(target: any, prop: string | number | symbol) { export function updateFunction(target: any, prop: any, value: any, receiver: any) { let current = ObjectField.MakeCopy(value); return (diff?: any) => { - if (true || !diff) { - diff = { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } }; - const oldValue = current; - const newValue = ObjectField.MakeCopy(value); - current = newValue; - if (!(value instanceof CursorField) && !(value?.some?.((v: any) => v instanceof CursorField))) { - UndoManager.AddEvent({ - redo() { receiver[prop] = newValue; }, - undo() { receiver[prop] = oldValue; } - }); - } + const op = diff?.op === "$addToSet" ? { '$addToSet': { ["fields." + prop]: SerializationHelper.Serialize(new List<Doc>(diff.items)) } } : + diff?.op === "$remFromSet" ? { '$remFromSet': { ["fields." + prop]: SerializationHelper.Serialize(new List<Doc>(diff.items)) } } + : { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } }; + const oldValue = current; + const newValue = ObjectField.MakeCopy(value); + current = newValue; + if (!(value instanceof CursorField) && !(value?.some?.((v: any) => v instanceof CursorField))) { + !receiver[UpdatingFromServer] && UndoManager.AddEvent( + diff?.op === "$addToSet" ? + { + redo: () => { + receiver[prop].push(...diff.items); + }, + undo: action(() => { + let curList = receiver[prop]; + //while (curList[ForwardUpates]) curList = curList[ForwardUpates]; + diff.items.forEach((doc: any) => { + const ind = curList.indexOf(doc.value()); + ind !== -1 && curList.splice(ind, 1); + }); + }) + } : + diff?.op === "$remFromSet" ? + { + redo: action(() => { + let curList = receiver[prop]; + diff.items.forEach((doc: any) => { + const ind = curList.indexOf(doc.value()); + ind !== -1 && curList.splice(ind, 1); + }); + }), + undo: () => receiver[prop].push(...diff.items) + } + : { + redo: () => receiver[prop] = newValue, + undo: () => receiver[prop] = oldValue + }); } - target[Update](diff); + target[Update](op); }; }
\ No newline at end of file |