diff --git a/app/assets/javascripts/app/frontend/controllers/home.js b/app/assets/javascripts/app/frontend/controllers/home.js index 8f0f6a4ab..a243058e1 100644 --- a/app/assets/javascripts/app/frontend/controllers/home.js +++ b/app/assets/javascripts/app/frontend/controllers/home.js @@ -105,16 +105,13 @@ angular.module('app.frontend') */ $scope.removeTag = function(tag) { - var validNotes = Note.filterDummyNotes(tag.notes); - if(validNotes == 0) { + if(confirm("Are you sure you want to delete this tag?")) { modelManager.setItemToBeDeleted(tag); // if no more notes, delete tag syncManager.sync(function(){ // force scope tags to update on sub directives $scope.safeApply(); }); - } else { - alert("To delete this tag, remove all its notes first."); } } diff --git a/app/assets/javascripts/app/frontend/controllers/notes.js b/app/assets/javascripts/app/frontend/controllers/notes.js index 29081f840..58bc072c3 100644 --- a/app/assets/javascripts/app/frontend/controllers/notes.js +++ b/app/assets/javascripts/app/frontend/controllers/notes.js @@ -82,6 +82,7 @@ angular.module('app.frontend') this.selectNote = function(note) { this.selectedNote = note; + note.conflict_of = null; // clear conflict this.selectionMade()(note); } diff --git a/app/assets/javascripts/app/frontend/controllers/tags.js b/app/assets/javascripts/app/frontend/controllers/tags.js index 8b5357480..e6eefbec4 100644 --- a/app/assets/javascripts/app/frontend/controllers/tags.js +++ b/app/assets/javascripts/app/frontend/controllers/tags.js @@ -55,6 +55,7 @@ angular.module('app.frontend') this.selectTag = function(tag) { this.willSelect()(tag); this.selectedTag = tag; + tag.conflict_of = null; // clear conflict this.selectionMade()(tag); } diff --git a/app/assets/javascripts/app/services/directives/views/editorMenu.js b/app/assets/javascripts/app/services/directives/views/editorMenu.js index 69b8c6a06..514f9ee6f 100644 --- a/app/assets/javascripts/app/services/directives/views/editorMenu.js +++ b/app/assets/javascripts/app/services/directives/views/editorMenu.js @@ -16,6 +16,7 @@ class EditorMenu { $scope.editorManager = editorManager; $scope.selectEditor = function(editor) { + editor.conflict_of = null; // clear conflict if applicable $scope.callback()(editor); } diff --git a/app/assets/javascripts/app/services/syncManager.js b/app/assets/javascripts/app/services/syncManager.js index 81f70a87a..7c47b8ef9 100644 --- a/app/assets/javascripts/app/services/syncManager.js +++ b/app/assets/javascripts/app/services/syncManager.js @@ -268,7 +268,29 @@ class SyncManager { handleItemsResponse(responseItems, omitFields) { EncryptionHelper.decryptMultipleItems(responseItems, this.authManager.keys()); - return this.modelManager.mapResponseItemsToLocalModelsOmittingFields(responseItems, omitFields); + var items = this.modelManager.mapResponseItemsToLocalModelsOmittingFields(responseItems, omitFields); + this.handleSyncConflicts(items); + return items; + } + + handleSyncConflicts(items) { + var needsSync = false; + for(var item of items) { + if(item.conflict_of) { + var original = this.modelManager.findItem(item.conflict_of); + // check if item contents are equal. If so, automatically delete conflict + if(JSON.stringify(item.structureParams()) === JSON.stringify(original.structureParams())) { + this.modelManager.setItemToBeDeleted(item); + needsSync = true; + } + } + } + + if(needsSync) { + setTimeout(function () { + this.sync(); + }.bind(this), 100); + } } clearSyncToken() { diff --git a/app/assets/templates/frontend/directives/editor-menu.html.haml b/app/assets/templates/frontend/directives/editor-menu.html.haml index fed6e6f9d..fae7ca3b9 100644 --- a/app/assets/templates/frontend/directives/editor-menu.html.haml +++ b/app/assets/templates/frontend/directives/editor-menu.html.haml @@ -14,6 +14,7 @@ %li.menu-item{"ng-repeat" => "editor in editorManager.externalEditors", "ng-click" => "selectEditor(editor)"} .pull-left{"style" => "width: 60%"} + %strong.red.medium{"ng-if" => "editor.conflict_of"} Conflicted copy .menu-item-title {{editor.name}} %a.faded{"ng-if" => "!editor.default", "ng-click" => "setDefaultEditor(editor); $event.stopPropagation();"} Set Default %a.red{"ng-if" => "editor.default", "ng-click" => "removeDefaultEditor(editor); $event.stopPropagation();"} Remove Default diff --git a/app/assets/templates/frontend/notes.html.haml b/app/assets/templates/frontend/notes.html.haml index ac5bd606b..d61dc9e0f 100644 --- a/app/assets/templates/frontend/notes.html.haml +++ b/app/assets/templates/frontend/notes.html.haml @@ -28,7 +28,8 @@ .infinite-scroll{"infinite-scroll" => "ctrl.paginate()", "can-load" => "true", "threshold" => "200"} .note{"ng-repeat" => "note in (ctrl.sortedNotes = (ctrl.tag.notes | filter: ctrl.filterNotes | orderBy: ctrl.sortBy:true | limitTo:ctrl.notesToDisplay))", "ng-click" => "ctrl.selectNote(note)", "ng-class" => "{'selected' : ctrl.selectedNote == note}"} - .name{"ng-if" => "note.title"} + %strong.red.medium{"ng-if" => "note.conflict_of"} Conflicted copy + .name{"ng-if" => "note.title || note.conflict_of"} {{note.title}} .note-preview {{note.text}} diff --git a/app/assets/templates/frontend/tags.html.haml b/app/assets/templates/frontend/tags.html.haml index dcc21d6e7..607651ab1 100644 --- a/app/assets/templates/frontend/tags.html.haml +++ b/app/assets/templates/frontend/tags.html.haml @@ -16,6 +16,7 @@ "ng-keyup" => "$event.keyCode == 13 && ctrl.saveTag($event, tag)", "mb-autofocus" => "true", "should-focus" => "ctrl.newTag || ctrl.editingTag == tag", "ng-change" => "ctrl.tagTitleDidChange(tag)", "ng-blur" => "ctrl.saveTag($event, tag)", "spellcheck" => "false"} .count {{ctrl.noteCount(tag)}} + .red.small.bold{"ng-if" => "tag.conflict_of"} Conflicted copy .menu{"ng-if" => "ctrl.selectedTag == tag"} %a.item{"ng-click" => "ctrl.selectedRenameTag($event, tag)", "ng-if" => "!ctrl.editingTag"} Rename %a.item{"ng-click" => "ctrl.saveTag($event, tag)", "ng-if" => "ctrl.editingTag"} Save