Fix references bug that prematurely saves data locally before all references could be properly retrieved and built

This commit is contained in:
Mo Bitar
2017-09-05 11:49:12 -05:00
parent 47fc4ef8c2
commit 407a235a15
7 changed files with 43 additions and 18 deletions

View File

@@ -37,7 +37,7 @@ angular.module('app.frontend')
}
}
})
.controller('EditorCtrl', function ($scope, $sce, $timeout, authManager, $rootScope, extensionManager, syncManager, modelManager, editorManager, themeManager, componentManager) {
.controller('EditorCtrl', function ($sce, $timeout, authManager, $rootScope, extensionManager, syncManager, modelManager, editorManager, themeManager, componentManager) {
this.componentManager = componentManager;
this.componentStack = [];

View File

@@ -113,7 +113,7 @@ class Item {
this.setDirty(true);
}
locallyClearAllReferences() {
removeReferencesNotPresentIn(references) {
}

View File

@@ -61,9 +61,15 @@ class Editor extends Item {
this.notes = [];
}
locallyClearAllReferences() {
super.locallyClearAllReferences();
this.notes = [];
removeReferencesNotPresentIn(references) {
super.removeReferencesNotPresentIn(references);
var uuids = references.map(function(ref){return ref.uuid});
this.notes.forEach(function(note){
if(!uuids.includes(note.uuid)) {
_.pull(this.notes, note);
}
}.bind(this))
}
potentialItemOfInterestHasChangedItsUUID(newItem, oldUUID, newUUID) {

View File

@@ -56,12 +56,16 @@ class Note extends Item {
this.tags = [];
}
locallyClearAllReferences() {
super.locallyClearAllReferences();
removeReferencesNotPresentIn(references) {
super.removeReferencesNotPresentIn(references);
var uuids = references.map(function(ref){return ref.uuid});
this.tags.forEach(function(tag){
_.pull(tag.notes, this);
if(!uuids.includes(tag.uuid)) {
_.pull(tag.notes, this);
_.pull(this.tags, tag);
}
}.bind(this))
this.tags = [];
}
isBeingRemovedLocally() {

View File

@@ -55,13 +55,14 @@ class Tag extends Item {
this.notes = [];
}
locallyClearAllReferences() {
super.locallyClearAllReferences();
removeReferencesNotPresentIn(references) {
var uuids = references.map(function(ref){return ref.uuid});
this.notes.forEach(function(note){
_.pull(note.tags, this);
if(!uuids.includes(note.uuid)) {
_.pull(note.tags, this);
_.pull(this.notes, note);
}
}.bind(this))
this.notes = [];
}
isBeingRemovedLocally() {

View File

@@ -198,20 +198,24 @@ class ModelManager {
}
resolveReferencesForItem(item) {
item.locallyClearAllReferences();
var contentObject = item.contentObject;
// If another client removes an item's references, this client won't pick up the removal unless
// we remove everything not present in the current list of references
item.removeReferencesNotPresentIn(contentObject.references);
if(!contentObject.references) {
return;
}
for(var reference of contentObject.references) {
var referencedItem = this.findItem(reference.uuid);
if(referencedItem) {
item.addItemAsRelationship(referencedItem);
referencedItem.addItemAsRelationship(item);
} else {
// console.log("Unable to find item:", reference.uuid);
// console.log("Unable to find reference:", reference.uuid, "for item:", item);
}
}
}

View File

@@ -187,6 +187,13 @@ class SyncManager {
this.syncStatus.current = 0;
}
// when doing a sync request that returns items greater than the limit, and thus subsequent syncs are required,
// we want to keep track of all retreived items, then save to local storage only once all items have been retrieved,
// so that relationships remain intact
if(!this.allRetreivedItems) {
this.allRetreivedItems = [];
}
var params = {};
params.limit = 150;
params.items = _.map(subItems, function(item){
@@ -209,6 +216,7 @@ class SyncManager {
this.$rootScope.$broadcast("sync:updated_token", this.syncToken);
var retrieved = this.handleItemsResponse(response.retrieved_items, null);
this.allRetreivedItems = this.allRetreivedItems.concat(retrieved);
// merge only metadata for saved items
// we write saved items to disk now because it clears their dirty status then saves
@@ -218,7 +226,6 @@ class SyncManager {
this.handleUnsavedItemsResponse(response.unsaved)
this.writeItemsToLocalStorage(saved, false, null);
this.writeItemsToLocalStorage(retrieved, false, null);
this.syncStatus.syncOpInProgress = false;
this.syncStatus.current += subItems.length;
@@ -239,6 +246,9 @@ class SyncManager {
this.sync(callback, options);
}.bind(this), 10); // wait 10ms to allow UI to update
} else {
this.writeItemsToLocalStorage(this.allRetreivedItems, false, null);
this.allRetreivedItems = [];
this.callQueuedCallbacksAndCurrent(callback, response);
this.$rootScope.$broadcast("sync:completed");
}