aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2020-10-06 19:14:06 -0400
committerbobzel <zzzman@gmail.com>2020-10-06 19:14:06 -0400
commitc65ca9da4ccdbb525ca7c4e50e7403cf6b543cbe (patch)
treea253c5589fc605f5138a110c84bc47ba0bedf647
parent031e29b1cf14f643f3b52c52f77785e71f011708 (diff)
fixes for undo with multi-users
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
-rw-r--r--src/fields/List.ts3
-rw-r--r--src/fields/util.ts55
-rw-r--r--src/server/websocket.ts35
4 files changed, 66 insertions, 29 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index fc3fd3a7c..1ddb709ac 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1160,7 +1160,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@action
onCursorMove = (e: React.PointerEvent) => {
- super.setCursorPosition(this.getTransform().transformPoint(e.clientX, e.clientY));
+ // super.setCursorPosition(this.getTransform().transformPoint(e.clientX, e.clientY));
}
diff --git a/src/fields/List.ts b/src/fields/List.ts
index d9bd54673..ceb538b2d 100644
--- a/src/fields/List.ts
+++ b/src/fields/List.ts
@@ -66,6 +66,7 @@ const listHandlers: any = {
this[Self].__realFields(); // coerce retrieving entire array
items = items.map(toObjectField);
const list = this[Self];
+ const removed = list.__fields.filter((item: any, i: number) => i >= start && i < start + deleteCount);
for (let i = 0; i < items.length; i++) {
const item = items[i];
//TODO Error checking to make sure parent doesn't already exist
@@ -76,7 +77,7 @@ const listHandlers: any = {
}
}
const res = list.__fields.splice(start, deleteCount, ...items);
- this[Update]();
+ this[Update](items.length === 0 && deleteCount ? { op: "$remFromSet", items: removed } : undefined);
return res.map(toRealField);
}),
unshift(...items: any[]) {
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 6e72675db..b251236d0 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -11,10 +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 {
throw new Error("Documents can't be modified in read-only mode");
}
@@ -95,7 +93,10 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number
} else {
DocServer.registerDocWithCachedUpdate(receiver, prop as string, curValue);
}
- UndoManager.AddEvent({
+ if (prop === "data-annotations") {
+ console.log("Yukc")
+ }
+ !receiver[UpdatingFromServer] && UndoManager.AddEvent({
redo: () => receiver[prop] = value,
undo: () => receiver[prop] = curValue
});
@@ -373,25 +374,43 @@ 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) => {
- const op = diff?.op === "$addToSet" ?
- { '$addToSet': { ["fields." + prop]: SerializationHelper.Serialize(new List<Doc>(diff.items)) } }
- : { '$set': { ["fields." + prop]: SerializationHelper.Serialize(value) } };
+ 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))) {
- UndoManager.AddEvent(diff?.op === "$addToSet" ?
- {
- redo: () => receiver[prop].push(...diff.items),
- undo: action(() => diff.items.forEach((doc: Doc) => {
- const ind = receiver[prop].indexOf(doc);
- ind !== -1 && receiver[prop].splice(ind, 1);
- }))
- }
- : {
- redo: () => receiver[prop] = newValue,
- undo: () => receiver[prop] = oldValue
- });
+ !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](op);
};
diff --git a/src/server/websocket.ts b/src/server/websocket.ts
index 221a01308..459fa520b 100644
--- a/src/server/websocket.ts
+++ b/src/server/websocket.ts
@@ -271,16 +271,13 @@ export namespace WebSocket {
return typeof value === "string" ? value : value[0];
}
- 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;
+ function addToListField(socket: Socket, diff: Diff, curListItems?: Transferable): void {
+ diff.diff.$set = diff.diff.$addToSet; delete 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
const updatefield = Array.from(Object.keys(diff.diff.$set))[0];
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;
- 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;
+ const curList = (curListItems as any)?.fields?.[updatefield.replace("fields.", "")]?.fields || [];
+ diff.diff.$set[updatefield].fields = [...curList, ...newListItems.filter((newItem: any) => !curList.some((curItem: any) => curItem.fieldId === newItem.fieldId))];
+ const sendBack = true;//curList.length !== prelen;
Database.Instance.update(diff.id, diff.diff,
() => {
if (sendBack) {
@@ -292,8 +289,28 @@ export namespace WebSocket {
}, false);
}
+ function remFromListField(socket: Socket, diff: Diff, curListItems?: Transferable): void {
+ diff.diff.$set = diff.diff.$remFromSet; delete diff.diff.$remFromSet;
+ const updatefield = Array.from(Object.keys(diff.diff.$set))[0];
+ const remListItems = diff.diff.$set[updatefield].fields;
+ const curList = (curListItems as any)?.fields?.[updatefield.replace("fields.", "")]?.fields || [];
+ diff.diff.$set[updatefield].fields = curList?.filter((curItem: any) => !remListItems.some((remItem: any) => remItem.fieldId === curItem.fieldId));
+ const sendBack = true;//curList.length + remListItems.length !== prelen;
+ Database.Instance.update(diff.id, diff.diff,
+ () => {
+ if (sendBack) {
+ const id = socket.id;
+ socket.id = "";
+ socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
+ socket.id = id;
+ } else socket.broadcast.emit(MessageStore.UpdateField.Message, diff);
+ }, false);
+ }
+
+
function UpdateField(socket: Socket, diff: Diff) {
- if (diff.diff.$addToSet) return GetRefField([diff.id, (result?: Transferable) => updateListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
+ if (diff.diff.$addToSet) return GetRefField([diff.id, (result?: Transferable) => addToListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
+ if (diff.diff.$remFromSet) return GetRefField([diff.id, (result?: Transferable) => remFromListField(socket, diff, result)]); // would prefer to have Mongo handle list additions direclty, but for now handle it on our own
Database.Instance.update(diff.id, diff.diff,
() => socket.broadcast.emit(MessageStore.UpdateField.Message, diff), false);
const docfield = diff.diff.$set || diff.diff.$unset;