From 75af353e8b81d7604e8a545cfc20808fe63e29c9 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Sun, 15 Apr 2018 10:29:47 -0500 Subject: [PATCH] Fix for issue where deleting an item offline would not immediately remove it from display, and would subsequently not resync the deleted item after connection was restored. --- .../services/encryption/encryptionHelper.js | 5 +- .../javascripts/app/services/modelManager.js | 71 ++++++++++++------- 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/app/assets/javascripts/app/services/encryption/encryptionHelper.js b/app/assets/javascripts/app/services/encryption/encryptionHelper.js index 7b20a9616..c724de309 100644 --- a/app/assets/javascripts/app/services/encryption/encryptionHelper.js +++ b/app/assets/javascripts/app/services/encryption/encryptionHelper.js @@ -136,7 +136,10 @@ class EncryptionHelper { static decryptMultipleItems(items, keys, throws) { for (var item of items) { - if(item.deleted == true) { + + // 4/15/18: Adding item.content == null clause. We still want to decrypt deleted items incase + // they were marked as dirty but not yet synced. Not yet sure why we had this requirement. + if(item.deleted == true && item.content == null) { continue; } diff --git a/app/assets/javascripts/app/services/modelManager.js b/app/assets/javascripts/app/services/modelManager.js index 366ed429e..d3b3b9a3b 100644 --- a/app/assets/javascripts/app/services/modelManager.js +++ b/app/assets/javascripts/app/services/modelManager.js @@ -150,19 +150,27 @@ class ModelManager { let contentType = json_obj["content_type"] || (item && item.content_type); var unknownContentType = !_.includes(this.acceptableContentTypes, contentType); + var isDirtyItemPendingDelete = false; if(json_obj.deleted == true || unknownContentType) { - if(item && !unknownContentType) { - modelsToNotifyObserversOf.push(item); - this.removeItemLocally(item); + if(json_obj.deleted && json_obj.dirty) { + // Item was marked as deleted but not yet synced + // We need to create this item as usual, but just not add it to indivudal arrays + // i.e add to this.items but not this.notes (so that it can be retrieved with getDirtyItems) + isDirtyItemPendingDelete = true; + } else { + if(item && !unknownContentType) { + modelsToNotifyObserversOf.push(item); + this.removeItemLocally(item); + } + continue; } - continue; } if(!item) { item = this.createItem(json_obj, true); } - this.addItem(item); + this.addItem(item, isDirtyItemPendingDelete); modelsToNotifyObserversOf.push(item); models.push(item); @@ -259,22 +267,30 @@ class ModelManager { return dup; } - addItems(items) { + addItem(item, globalOnly = false) { + this.addItems([item], globalOnly); + } + + addItems(items, globalOnly = false) { items.forEach(function(item){ - if(item.content_type == "Tag") { - if(!_.find(this.tags, {uuid: item.uuid})) { - this.tags.splice(_.sortedIndexBy(this.tags, item, function(item){ - if (item.title) return item.title.toLowerCase(); - else return '' - }), 0, item); - } - } else if(item.content_type == "Note") { - if(!_.find(this.notes, {uuid: item.uuid})) { - this.notes.unshift(item); - } - } else if(item.content_type == "Extension") { - if(!_.find(this._extensions, {uuid: item.uuid})) { - this._extensions.unshift(item); + // In some cases, you just want to add the item to this.items, and not to the individual arrays + // This applies when you want to keep an item syncable, but not display it via the individual arrays + if(!globalOnly) { + if(item.content_type == "Tag") { + if(!_.find(this.tags, {uuid: item.uuid})) { + this.tags.splice(_.sortedIndexBy(this.tags, item, function(item){ + if (item.title) return item.title.toLowerCase(); + else return '' + }), 0, item); + } + } else if(item.content_type == "Note") { + if(!_.find(this.notes, {uuid: item.uuid})) { + this.notes.unshift(item); + } + } else if(item.content_type == "Extension") { + if(!_.find(this._extensions, {uuid: item.uuid})) { + this._extensions.unshift(item); + } } } @@ -292,10 +308,6 @@ class ModelManager { }), 0, tag); } - addItem(item) { - this.addItems([item]); - } - resolveReferencesForItem(item, markReferencesDirty = false) { var contentObject = item.contentObject; @@ -363,6 +375,17 @@ class ModelManager { if(!item.dummy) { item.setDirty(true); } + + // remove from relevant array, but don't remove from all items. + // This way, it's removed from the display, but still synced via get dirty items + if(item.content_type == "Tag") { + _.pull(this.tags, item); + } else if(item.content_type == "Note") { + _.pull(this.notes, item); + } else if(item.content_type == "Extension") { + _.pull(this._extensions, item); + } + item.removeAndDirtyAllRelationships(); }