aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fields/List.ts8
-rw-r--r--src/fields/util.ts3
-rw-r--r--src/server/websocket.ts62
3 files changed, 68 insertions, 5 deletions
diff --git a/src/fields/List.ts b/src/fields/List.ts
index 9c7794813..eb735dec2 100644
--- a/src/fields/List.ts
+++ b/src/fields/List.ts
@@ -77,10 +77,16 @@ const listHandlers: any = {
item[OnUpdate] = updateFunction(list, i + start, item, this);
}
}
+ let hintArray: {val : any, index : number}[] = [];
+ for(let i = start; i < start + deleteCount; i++) {
+ hintArray.push({val : list.__fields[i], index : i});
+ }
const res = list.__fields.splice(start, deleteCount, ...items);
+ // console.log(hintArray);
+ // console.log(list.__fields);
this[Update](
items.length === 0 && deleteCount
- ? { op: '$remFromSet', items: removed, length: list.__fields.length }
+ ? { op: '$remFromSet', items: removed, hint : { start : start, deleteCount : deleteCount, hintArray : hintArray}, length: list.__fields.length }
: items.length && !deleteCount && start === list.__fields.length
? { op: '$addToSet', items, length: list.__fields.length }
: undefined
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 92f3a69eb..254b70fa7 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -37,6 +37,7 @@ import { RichTextField } from './RichTextField';
import { SchemaHeaderField } from './SchemaHeaderField';
import { ComputedField } from './ScriptField';
import { ScriptCast, StrCast } from './Types';
+import { blue } from 'colors';
function _readOnlySetter(): never {
throw new Error("Documents can't be modified in read-only mode");
@@ -377,7 +378,7 @@ export function updateFunction(target: any, prop: any, value: any, receiver: any
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)) } }
+ ? { $remFromSet: { ['fields.' + prop]: SerializationHelper.Serialize(new List<Doc>(diff.items)), hint : diff.hint } }
: { $set: { ['fields.' + prop]: SerializationHelper.Serialize(value) } };
!op.$set && ((op as any).length = diff.length);
const prevValue = ObjectField.MakeCopy(lastValue as List<any>);
diff --git a/src/server/websocket.ts b/src/server/websocket.ts
index 2acdaa5a3..74b5dacaa 100644
--- a/src/server/websocket.ts
+++ b/src/server/websocket.ts
@@ -317,21 +317,77 @@ export namespace WebSocket {
);
}
+ function findClosestIndex(list: any, indexesToDelete: number[], value: any, hintIndex : number) {
+ let closestIndex = -1;
+ for(let i = 0; i < list.length; i++) {
+ if(list[i] == value && !indexesToDelete.includes(i)) {
+ if(Math.abs(i - hintIndex) < Math.abs(closestIndex - hintIndex)) {
+ closestIndex = i;
+ }
+ }
+ }
+ return closestIndex;
+ }
+
function remFromListField(socket: Socket, diff: Diff, curListItems?: Transferable): void {
+ // console.log("##### %O", diff);
diff.diff.$set = diff.diff.$remFromSet;
delete diff.diff.$remFromSet;
+ // console.log(JSON.stringify(diff));
const updatefield = Array.from(Object.keys(diff.diff.$set))[0];
+ // console.log("websocket/remfromlist: UPDATE FIELD: " + updatefield);
const remListItems = diff.diff.$set[updatefield].fields;
const curList = (curListItems as any)?.fields?.[updatefield.replace('fields.', '')]?.fields.filter((f: any) => f !== null) || [];
- diff.diff.$set[updatefield].fields = curList?.filter(
- (curItem: any) => !remListItems.some((remItem: any) => (remItem.fieldId ? remItem.fieldId === curItem.fieldId : remItem.heading ? remItem.heading === curItem.heading : remItem === curItem))
- );
+ const hint = diff.diff.$set.hint;
+ // console.log(remListItems);
+ // console.log(curList);
+
+
+ if(hint) {
+ // console.log("websocket/remfromlist: %O", hint);
+ // console.log(findClosestIndex([5, 5, 3], [], 5, 0));
+ // console.log(findClosestIndex([5, 5, 3], [0], 5, 1));
+ let indexesToRemove: number[] = [];
+ for(let i = 0; i < hint.deleteCount; i++) {
+ // console.log("VALUE: %d", remListItems[i]);
+ // console.log("HINT INDEX: %d", i + hint.start);
+ if(curList[i + hint.start] == remListItems[i]) {
+ indexesToRemove.push(i + hint.start);
+ continue;
+ }
+
+ let closestIndex = findClosestIndex(curList, indexesToRemove, remListItems[i], i + hint.start);
+ if(closestIndex != -1) {
+ indexesToRemove.push(closestIndex);
+ } else {
+ console.log("Item to delete was not found - index = -1");
+ }
+ }
+
+ // console.log("INDEXES TO REMOVE: ", indexesToRemove);
+ diff.diff.$set[updatefield].fields = curList?.filter(
+ (curItem: any, index : number) => !(indexesToRemove.includes(index))
+ );
+ // console.log("websocket/remfromlist: newdiff: %O", diff.diff.$set[updatefield].fields);
+ } else {
+ diff.diff.$set[updatefield].fields = curList?.filter(
+ (curItem: any) => !remListItems.some((remItem: any) => (remItem.fieldId ? remItem.fieldId === curItem.fieldId :
+ remItem.heading ? remItem.heading === curItem.heading : remItem === curItem))
+ );
+ // console.log("websocket/remfromlist: newdiff: %O", diff.diff.$set[updatefield].fields);
+ }
+
+
const sendBack = diff.diff.length !== diff.diff.$set[updatefield].fields.length;
+ // console.log("websocket/remfromlist: DIFFY " + JSON.stringify(diff.diff.$set));
+ // console.log("websocket/remfromlist: DIFF LENGTH " + diff.diff.length);
+ // console.log("websocket/remfromlist: DIFF $SET " + diff.diff.$set[updatefield].fields);
delete diff.diff.length;
Database.Instance.update(
diff.id,
diff.diff,
() => {
+ // console.log("websocket/remfromlist: lambda: %s", JSON.stringify(diff))
if (sendBack) {
console.log('SEND BACK');
const id = socket.id;