diff options
-rw-r--r-- | src/client/views/collections/CollectionView.tsx | 1 | ||||
-rw-r--r-- | src/fields/List.ts | 2 | ||||
-rw-r--r-- | src/fields/util.ts | 28 | ||||
-rw-r--r-- | src/server/websocket.ts | 10 |
4 files changed, 25 insertions, 16 deletions
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 0ef3dd6cd..80e9b41ad 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -196,7 +196,6 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus const recent = Cast(Doc.UserDoc().myRecentlyClosedDocs, Doc) as Doc; toRemove.forEach(doc => { const ind = (targetDataDoc[this.props.fieldKey] as List<Doc>).indexOf(doc); - (targetDataDoc[this.props.fieldKey] as List<Doc>).splice(ind, 0); if (ind !== -1) { Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc); recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true); diff --git a/src/fields/List.ts b/src/fields/List.ts index dca8d111c..d9bd54673 100644 --- a/src/fields/List.ts +++ b/src/fields/List.ts @@ -43,7 +43,7 @@ const listHandlers: any = { } } const res = list.__fields.push(...items); - this[Update]("$addToSet"); + this[Update]({ op: "$addToSet", items }); return res; }), reverse() { diff --git a/src/fields/util.ts b/src/fields/util.ts index 90446f531..b6128f5e6 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -11,6 +11,8 @@ import { ComputedField } from "./ScriptField"; import { ScriptCast, StrCast } from "./Types"; import { returnZero } from "../Utils"; import CursorField from "./CursorField"; +import { undo } from "prosemirror-history"; +import { List } from "./List"; function _readOnlySetter(): never { @@ -371,20 +373,26 @@ 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 (diff === "$addToSet") { - diff = { '$addToSet': { ["fields." + prop]: SerializationHelper.Serialize(value) } }; - } else { - diff = { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } }; - } + const op = diff?.op === "$addToSet" ? + { '$addToSet': { ["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))) { - UndoManager.AddEvent({ - redo() { receiver[prop] = newValue; }, - undo() { receiver[prop] = oldValue; } - }); + UndoManager.AddEvent(diff?.op === "$addToSet" ? + { + redo: () => receiver[prop].push(...(newValue as List<Doc>)), + undo: action(() => (newValue as List<Doc>).forEach(doc => { + const ind = receiver[prop].indexOf(doc); + ind !== -1 && receiver[prop].splice(ind, 1); + })) + } + : { + redo: () => receiver[prop] = newValue, + undo: () => receiver[prop] = oldValue + }); } - target[Update](diff); + target[Update](op); }; }
\ No newline at end of file diff --git a/src/server/websocket.ts b/src/server/websocket.ts index 3687ef876..221a01308 100644 --- a/src/server/websocket.ts +++ b/src/server/websocket.ts @@ -271,14 +271,16 @@ export namespace WebSocket { return typeof value === "string" ? value : value[0]; } - function updateListField(socket: Socket, diff: Diff, results?: Transferable): void { + function updateListField(socket: Socket, diff: Diff, curListItems?: Transferable): void { diff.diff.$set = diff.diff.$addToSet; // convert add to set to a query of the current fields, and then a set of the composition of the new fields with the old ones delete diff.diff.$addToSet; const updatefield = Array.from(Object.keys(diff.diff.$set))[0]; - const list = (results as any).fields?.[updatefield.replace("fields.", "")]?.fields; + const newListItems = diff.diff.$set[updatefield].fields; + const curList = (curListItems as any).fields?.[updatefield.replace("fields.", "")]?.fields; const prelen = diff.diff.$set[updatefield].fields.length; - list?.forEach((item: any) => !diff.diff.$set[updatefield].fields.some((x: any) => x.fieldId === item.fieldId) && diff.diff.$set[updatefield].fields.push(item)); - const sendBack = diff.diff.$set[updatefield].fields.length !== prelen; + let insInd = 0; + curList?.forEach((curItem: any) => !newListItems.some((newItem: any) => newItem.fieldId === curItem.fieldId) && newListItems.splice(insInd++, 0, curItem)); + const sendBack = curList.length !== prelen; Database.Instance.update(diff.id, diff.diff, () => { if (sendBack) { |