From 054eae6adf14c658d108738fe88a1ef93382ca52 Mon Sep 17 00:00:00 2001 From: Amit Date: Thu, 9 Feb 2017 00:15:34 +0900 Subject: [PATCH 01/16] select first note in list, after delete --- app/assets/javascripts/app/frontend/controllers/editor.js | 7 +++++++ app/assets/javascripts/app/frontend/controllers/notes.js | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/app/assets/javascripts/app/frontend/controllers/editor.js b/app/assets/javascripts/app/frontend/controllers/editor.js index 51ceee65f..6834360eb 100644 --- a/app/assets/javascripts/app/frontend/controllers/editor.js +++ b/app/assets/javascripts/app/frontend/controllers/editor.js @@ -239,9 +239,16 @@ angular.module('app.frontend') if(confirm("Are you sure you want to delete this note?")) { this.remove()(this.note); this.showMenu = false; + this.notifyDelete(); } } + this.notifyDelete = function() { + $timeout(function() { + $rootScope.$broadcast("noteDeleted"); + }.bind(this), 500); + } + this.clickedEditNote = function() { this.editorMode = 'edit'; this.focusEditor(100); diff --git a/app/assets/javascripts/app/frontend/controllers/notes.js b/app/assets/javascripts/app/frontend/controllers/notes.js index 5bb7fba5a..fc6bc70e0 100644 --- a/app/assets/javascripts/app/frontend/controllers/notes.js +++ b/app/assets/javascripts/app/frontend/controllers/notes.js @@ -30,6 +30,10 @@ angular.module('app.frontend') this.showMenu = false; }.bind(this)) + $rootScope.$on("noteDeleted", function() { + this.selectFirstNote(false); + }.bind(this)) + var isFirstLoad = true; this.notesToDisplay = 20; From ac2661bc6e7bc0aad83c2a4bb3db82a05383b6e3 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Sun, 26 Feb 2017 21:10:49 -0600 Subject: [PATCH 02/16] editor data --- .../app/frontend/controllers/editor.js | 10 ++++++++-- .../app/frontend/models/app/editor.js | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/app/frontend/controllers/editor.js b/app/assets/javascripts/app/frontend/controllers/editor.js index 3254d78f8..d12c50b13 100644 --- a/app/assets/javascripts/app/frontend/controllers/editor.js +++ b/app/assets/javascripts/app/frontend/controllers/editor.js @@ -53,8 +53,14 @@ angular.module('app.frontend') } else { var id = event.data.id; var text = event.data.text; - if(this.note.uuid == id) { + var data = event.data.data; + + if(this.note.uuid === id) { this.note.text = text; + var changesMade = this.customEditor.setData(id, data); + if(changesMade) { + this.customEditor.setDirty(true); + } this.changesMade(); } } @@ -103,7 +109,7 @@ angular.module('app.frontend') this.postNoteToExternalEditor = function() { var externalEditorElement = document.getElementById("editor-iframe"); if(externalEditorElement) { - externalEditorElement.contentWindow.postMessage({text: this.note.text, id: this.note.uuid}, '*'); + externalEditorElement.contentWindow.postMessage({text: this.note.text, data: this.customEditor.dataForKey(this.note.uuid), id: this.note.uuid}, '*'); } } diff --git a/app/assets/javascripts/app/frontend/models/app/editor.js b/app/assets/javascripts/app/frontend/models/app/editor.js index 2b823d3a5..9cff50789 100644 --- a/app/assets/javascripts/app/frontend/models/app/editor.js +++ b/app/assets/javascripts/app/frontend/models/app/editor.js @@ -8,12 +8,14 @@ class Editor extends Item { super.mapContentToLocalProperties(contentObject) this.url = contentObject.url; this.name = contentObject.name; + this.data = contentObject.data || {}; } structureParams() { var params = { url: this.url, - name: this.name + name: this.name, + data: this.data }; _.merge(params, super.structureParams()); @@ -27,4 +29,17 @@ class Editor extends Item { get content_type() { return "SN|Editor"; } + + setData(key, value) { + var dataHasChanged = JSON.stringify(this.data[key]) !== JSON.stringify(value); + if(dataHasChanged) { + this.data[key] = value; + return true; + } + return false; + } + + dataForKey(key) { + return this.data[key] || {}; + } } From fc6fc10ceb24de10a97840bbb7a79b7161551d3b Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 27 Feb 2017 08:02:10 -0600 Subject: [PATCH 03/16] server,email,pw as url params --- app/assets/javascripts/app/frontend/controllers/home.js | 9 ++++++++- app/assets/javascripts/app/frontend/routes.js | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/app/frontend/controllers/home.js b/app/assets/javascripts/app/frontend/controllers/home.js index ea70d15e6..6522171f1 100644 --- a/app/assets/javascripts/app/frontend/controllers/home.js +++ b/app/assets/javascripts/app/frontend/controllers/home.js @@ -1,5 +1,12 @@ angular.module('app.frontend') -.controller('HomeCtrl', function ($scope, $rootScope, $timeout, modelManager, syncManager, authManager) { +.controller('HomeCtrl', function ($scope, $stateParams, $rootScope, $timeout, modelManager, syncManager, authManager) { + + if($stateParams.server && $stateParams.email && authManager.offline()) { + authManager.login($stateParams.server, $stateParams.email, $stateParams.pw, function(response){ + window.location.reload(); + }) + } + syncManager.loadLocalItems(function(items) { $scope.$apply(); diff --git a/app/assets/javascripts/app/frontend/routes.js b/app/assets/javascripts/app/frontend/routes.js index f1f9322fa..687d4cab9 100644 --- a/app/assets/javascripts/app/frontend/routes.js +++ b/app/assets/javascripts/app/frontend/routes.js @@ -7,7 +7,7 @@ angular.module('app.frontend') }) .state('home', { - url: '/', + url: '/?server&email&pw', parent: 'base', views: { 'content@' : { From b4821073cc5b5e6bdcd87dba5ee637376e584859 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 27 Feb 2017 08:03:14 -0600 Subject: [PATCH 04/16] rm log --- .../javascripts/app/services/directives/views/accountMenu.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/assets/javascripts/app/services/directives/views/accountMenu.js b/app/assets/javascripts/app/services/directives/views/accountMenu.js index e243a35cb..4b2046284 100644 --- a/app/assets/javascripts/app/services/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/services/directives/views/accountMenu.js @@ -82,7 +82,6 @@ class AccountMenu { $scope.loginSubmitPressed = function() { $scope.formData.status = "Generating Login Keys..."; - console.log("logging in with url", $scope.formData.url); $timeout(function(){ authManager.login($scope.formData.url, $scope.formData.email, $scope.formData.user_password, function(response){ if(!response || response.error) { From 7c01b22159836243c4dd5f00faf0d0d0ce693dd1 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 27 Feb 2017 09:12:30 -0600 Subject: [PATCH 05/16] allow iframe --- app/controllers/application_controller.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2d6b04dea..43b6f0688 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,10 +1,10 @@ class ApplicationController < ActionController::Base - # Prevent CSRF attacks by raising an exception. - # For APIs, you may want to use :null_session instead. protect_from_forgery with: :null_session after_action :set_csrf_cookie + after_action :allow_iframe + layout :false def frontend @@ -13,8 +13,13 @@ class ApplicationController < ActionController::Base rescue_from ActionView::MissingTemplate do |exception| end + protected + def allow_iframe + response.headers.except! 'X-Frame-Options' + end + def set_app_domain @appDomain = request.domain @appDomain << ':' + request.port.to_s unless request.port.blank? From 646819ebdc9283f36e892cde8cba5b582dcc14ae Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 27 Feb 2017 11:43:19 -0600 Subject: [PATCH 06/16] auto sign in function --- .../app/frontend/controllers/home.js | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/app/frontend/controllers/home.js b/app/assets/javascripts/app/frontend/controllers/home.js index 6522171f1..e59ece731 100644 --- a/app/assets/javascripts/app/frontend/controllers/home.js +++ b/app/assets/javascripts/app/frontend/controllers/home.js @@ -1,10 +1,27 @@ angular.module('app.frontend') .controller('HomeCtrl', function ($scope, $stateParams, $rootScope, $timeout, modelManager, syncManager, authManager) { - if($stateParams.server && $stateParams.email && authManager.offline()) { - authManager.login($stateParams.server, $stateParams.email, $stateParams.pw, function(response){ - window.location.reload(); - }) + function autoSignInFromParams() { + if(!authManager.offline()) { + // check if current account + if(syncManager.serverURL == $stateParams.server && authManager.user.email == $stateParams.email) { + // already signed in, return + return; + } else { + // sign out + syncManager.destroyLocalData(function(){ + window.location.reload(); + }) + } + } else { + authManager.login($stateParams.server, $stateParams.email, $stateParams.pw, function(response){ + window.location.reload(); + }) + } + } + + if($stateParams.server && $stateParams.email) { + autoSignInFromParams(); } syncManager.loadLocalItems(function(items) { From 34bb12748900d2724e93355c2e885be87ad114aa Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 27 Feb 2017 11:44:05 -0600 Subject: [PATCH 07/16] remove fullscreen shortcut --- .../app/frontend/controllers/editor.js | 19 ------------------- .../templates/frontend/editor.html.haml | 1 - 2 files changed, 20 deletions(-) diff --git a/app/assets/javascripts/app/frontend/controllers/editor.js b/app/assets/javascripts/app/frontend/controllers/editor.js index d12c50b13..cc3e8bf4b 100644 --- a/app/assets/javascripts/app/frontend/controllers/editor.js +++ b/app/assets/javascripts/app/frontend/controllers/editor.js @@ -15,25 +15,6 @@ angular.module('app.frontend') bindToController: true, link:function(scope, elem, attrs, ctrl) { - - var handler = function(event) { - if (event.ctrlKey || event.metaKey) { - switch (String.fromCharCode(event.which).toLowerCase()) { - case 'o': - event.preventDefault(); - $timeout(function(){ - ctrl.toggleFullScreen(); - }) - break; - } - } - }; - - window.addEventListener('keydown', handler); - scope.$on('$destroy', function(){ - window.removeEventListener('keydown', handler); - }) - scope.$watch('ctrl.note', function(note, oldNote){ if(note) { ctrl.setNote(note, oldNote); diff --git a/app/assets/templates/frontend/editor.html.haml b/app/assets/templates/frontend/editor.html.haml index e8956bb3b..f16bfb3ed 100644 --- a/app/assets/templates/frontend/editor.html.haml +++ b/app/assets/templates/frontend/editor.html.haml @@ -19,7 +19,6 @@ %ul.dropdown-menu.dropdown-menu-left.nt-dropdown-menu.dark{"ng-if" => "ctrl.showMenu"} %li{"ng-click" => "ctrl.selectedMenuItem(); ctrl.toggleFullScreen()"} .text Toggle Fullscreen - .shortcut Cmd + O %li{"ng-click" => "ctrl.deleteNote()"} .text Delete From 8462482f461b1a3c810fe8ef26c9802042767dc9 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 27 Feb 2017 12:31:32 -0600 Subject: [PATCH 08/16] note selection adjustment --- .../javascripts/app/frontend/controllers/home.js | 7 ++++--- .../javascripts/app/frontend/controllers/notes.js | 15 +++------------ app/assets/templates/frontend/notes.html.haml | 2 +- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/app/assets/javascripts/app/frontend/controllers/home.js b/app/assets/javascripts/app/frontend/controllers/home.js index e59ece731..9ee571cb2 100644 --- a/app/assets/javascripts/app/frontend/controllers/home.js +++ b/app/assets/javascripts/app/frontend/controllers/home.js @@ -34,10 +34,11 @@ angular.module('app.frontend') }, 30000); }); - $scope.allTag = new Tag({all: true}); - $scope.allTag.title = "All"; + var allTag = new Tag({all: true}); + allTag.title = "All"; $scope.tags = modelManager.tags; - $scope.allTag.notes = modelManager.notes; + allTag.notes = modelManager.notes; + $scope.allTag = allTag; /* Editor Callbacks diff --git a/app/assets/javascripts/app/frontend/controllers/notes.js b/app/assets/javascripts/app/frontend/controllers/notes.js index 76ee180f0..9f7b13fa4 100644 --- a/app/assets/javascripts/app/frontend/controllers/notes.js +++ b/app/assets/javascripts/app/frontend/controllers/notes.js @@ -32,8 +32,6 @@ angular.module('app.frontend') this.showMenu = false; }.bind(this)) - var isFirstLoad = true; - this.notesToDisplay = 20; this.paginate = function() { this.notesToDisplay += 20 @@ -51,16 +49,9 @@ angular.module('app.frontend') tag.notes.forEach(function(note){ note.visible = true; }) - this.selectFirstNote(false); - if(isFirstLoad) { - $timeout(function(){ - this.createNewNote(); - isFirstLoad = false; - }.bind(this)) - } else if(tag.notes.length == 0) { - this.createNewNote(); - } + var createNew = tag.notes.length == 0; + this.selectFirstNote(createNew); } this.selectedTagDelete = function() { @@ -69,7 +60,7 @@ angular.module('app.frontend') } this.selectFirstNote = function(createNew) { - var visibleNotes = this.tag.notes.filter(function(note){ + var visibleNotes = this.sortedNotes.filter(function(note){ return note.visible; }); diff --git a/app/assets/templates/frontend/notes.html.haml b/app/assets/templates/frontend/notes.html.haml index f259f62c8..e7b1aa5c2 100644 --- a/app/assets/templates/frontend/notes.html.haml +++ b/app/assets/templates/frontend/notes.html.haml @@ -28,7 +28,7 @@ .scrollable .infinite-scroll{"infinite-scroll" => "ctrl.paginate()", "can-load" => "true", "threshold" => "200"} - .note{"ng-repeat" => "note in ctrl.tag.notes | filter: ctrl.filterNotes | orderBy: ctrl.sortBy:true | limitTo:ctrl.notesToDisplay", + .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"} {{note.title}} From e08c284a30e15e9b121078c17ce6563cbfbe6086 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 27 Feb 2017 12:40:42 -0600 Subject: [PATCH 09/16] rename file --- app/assets/templates/frontend/editor.html.haml | 2 +- app/assets/templates/frontend/notes.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/templates/frontend/editor.html.haml b/app/assets/templates/frontend/editor.html.haml index f16bfb3ed..ee505a48d 100644 --- a/app/assets/templates/frontend/editor.html.haml +++ b/app/assets/templates/frontend/editor.html.haml @@ -12,7 +12,7 @@ %ul.nav %li.dropdown.pull-left.mr-10{"click-outside" => "ctrl.showMenu = false;", "is-open" => "ctrl.showMenu"} %a.dropdown-toggle{"ng-click" => "ctrl.showMenu = !ctrl.showMenu; ctrl.showExtensions = false;"} - File + Menu %span.caret %span.sr-only diff --git a/app/assets/templates/frontend/notes.html.haml b/app/assets/templates/frontend/notes.html.haml index e7b1aa5c2..e6869f2d6 100644 --- a/app/assets/templates/frontend/notes.html.haml +++ b/app/assets/templates/frontend/notes.html.haml @@ -10,7 +10,7 @@ %ul.nav.nav-pills %li.dropdown %a.dropdown-toggle{"ng-click" => "ctrl.showMenu = !ctrl.showMenu"} - Tag options + Menu %span.caret %span.sr-only From 1f90bf028690b3576d9c298feb0f875341d27f65 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 27 Feb 2017 13:59:11 -0600 Subject: [PATCH 10/16] editor note references --- .../app/frontend/controllers/editor.js | 23 ++++++++--- .../app/frontend/models/app/editor.js | 41 +++++++++++++++++++ .../app/frontend/models/app/note.js | 2 +- .../app/frontend/models/local/itemParams.js | 2 +- .../javascripts/app/services/modelManager.js | 18 +++++--- .../javascripts/app/services/syncManager.js | 1 - 6 files changed, 74 insertions(+), 13 deletions(-) diff --git a/app/assets/javascripts/app/frontend/controllers/editor.js b/app/assets/javascripts/app/frontend/controllers/editor.js index cc3e8bf4b..04252b04f 100644 --- a/app/assets/javascripts/app/frontend/controllers/editor.js +++ b/app/assets/javascripts/app/frontend/controllers/editor.js @@ -52,8 +52,10 @@ angular.module('app.frontend') this.showMenu = false; this.loadTagsString(); - if(note.editorUrl) { - this.customEditor = this.editorForUrl(note.editorUrl); + var editor = this.editorForNote(note); + + if(editor) { + this.customEditor = editor; this.postNoteToExternalEditor(); } else { this.customEditor = null; @@ -75,16 +77,27 @@ angular.module('app.frontend') this.selectedEditor = function(editor) { this.showEditorMenu = false; if(editor.default) { + if(this.customEditor) { + this.customEditor.removeItemAsRelationship(this.note); + this.customEditor.setDirty(true); + } this.customEditor = null; } else { this.customEditor = editor; + this.customEditor.addItemAsRelationship(this.note); + this.customEditor.setDirty(true); } - this.note.editorUrl = editor.url; }.bind(this) - this.editorForUrl = function(url) { + this.editorForNote = function(note) { var editors = modelManager.itemsForContentType("SN|Editor"); - return editors.filter(function(editor){return editor.url == url})[0]; + for(var editor of editors) { + // console.log(editor.notes, editor.references); + if(_.includes(editor.notes, note)) { + return editor; + } + } + return null; } this.postNoteToExternalEditor = function() { diff --git a/app/assets/javascripts/app/frontend/models/app/editor.js b/app/assets/javascripts/app/frontend/models/app/editor.js index 9cff50789..49e84666d 100644 --- a/app/assets/javascripts/app/frontend/models/app/editor.js +++ b/app/assets/javascripts/app/frontend/models/app/editor.js @@ -2,6 +2,9 @@ class Editor extends Item { constructor(json_obj) { super(json_obj); + if(!this.notes) { + this.notes = []; + } } mapContentToLocalProperties(contentObject) { @@ -22,6 +25,44 @@ class Editor extends Item { return params; } + referenceParams() { + var references = _.map(this.notes, function(note){ + return {uuid: note.uuid, content_type: note.content_type}; + }) + + return references; + } + + addItemAsRelationship(item) { + if(item.content_type == "Note") { + if(!_.find(this.notes, item)) { + this.notes.push(item); + } + } + super.addItemAsRelationship(item); + } + + removeItemAsRelationship(item) { + if(item.content_type == "Note") { + _.pull(this.notes, item); + } + super.removeItemAsRelationship(item); + } + + removeAllRelationships() { + super.removeAllRelationships(); + this.notes = []; + } + + locallyClearAllReferences() { + super.locallyClearAllReferences(); + this.notes = []; + } + + allReferencedObjects() { + return this.notes; + } + toJSON() { return {uuid: this.uuid} } diff --git a/app/assets/javascripts/app/frontend/models/app/note.js b/app/assets/javascripts/app/frontend/models/app/note.js index e79a64682..58cd84292 100644 --- a/app/assets/javascripts/app/frontend/models/app/note.js +++ b/app/assets/javascripts/app/frontend/models/app/note.js @@ -62,7 +62,7 @@ class Note extends Item { _.pull(tag.notes, this); }.bind(this)) this.tags = []; - } + } isBeingRemovedLocally() { this.tags.forEach(function(tag){ diff --git a/app/assets/javascripts/app/frontend/models/local/itemParams.js b/app/assets/javascripts/app/frontend/models/local/itemParams.js index 22d7405ce..396a51bd1 100644 --- a/app/assets/javascripts/app/frontend/models/local/itemParams.js +++ b/app/assets/javascripts/app/frontend/models/local/itemParams.js @@ -16,7 +16,7 @@ class ItemParams { } paramsForLocalStorage() { - this.additionalFields = ["updated_at", "dirty", "editorUrl"]; + this.additionalFields = ["updated_at", "dirty"]; this.forExportFile = true; return this.__params(); } diff --git a/app/assets/javascripts/app/services/modelManager.js b/app/assets/javascripts/app/services/modelManager.js index ef67bc86a..f5b5c04ac 100644 --- a/app/assets/javascripts/app/services/modelManager.js +++ b/app/assets/javascripts/app/services/modelManager.js @@ -59,7 +59,9 @@ class ModelManager { } mapResponseItemsToLocalModelsOmittingFields(items, omitFields) { - var models = []; + var models = [], processedObjects = []; + + // first loop should add and process items for (var json_obj of items) { json_obj = _.omit(json_obj, omitFields || []) var item = this.findItem(json_obj["uuid"]); @@ -80,11 +82,16 @@ class ModelManager { this.addItem(item); - if(json_obj.content) { - this.resolveReferencesForItem(item); - } - models.push(item); + processedObjects.push(json_obj); + } + + // second loop should process references + for (var index in processedObjects) { + var json_obj = processedObjects[index]; + if(json_obj.content) { + this.resolveReferencesForItem(models[index]); + } } this.notifySyncObserversOfModels(models); @@ -174,6 +181,7 @@ class ModelManager { return; } + for(var reference of contentObject.references) { var referencedItem = this.findItem(reference.uuid); if(referencedItem) { diff --git a/app/assets/javascripts/app/services/syncManager.js b/app/assets/javascripts/app/services/syncManager.js index ddabf436d..e8ebb82df 100644 --- a/app/assets/javascripts/app/services/syncManager.js +++ b/app/assets/javascripts/app/services/syncManager.js @@ -187,7 +187,6 @@ class SyncManager { var saved = this.handleItemsResponse(response.saved_items, omitFields); this.handleUnsavedItemsResponse(response.unsaved) - this.writeItemsToLocalStorage(saved, false, null); this.writeItemsToLocalStorage(retrieved, false, null); From ba68e287ced983dc8ac414eec318af803e350736 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Mon, 27 Feb 2017 20:19:57 -0600 Subject: [PATCH 11/16] no new note on launch --- .../app/frontend/controllers/editor.js | 4 ---- .../app/frontend/controllers/home.js | 8 +++++--- .../app/frontend/controllers/notes.js | 18 +++++++++++++++--- app/assets/templates/frontend/editor.html.haml | 6 +++--- app/assets/templates/frontend/home.html.haml | 2 +- app/assets/templates/frontend/notes.html.haml | 4 ++-- 6 files changed, 26 insertions(+), 16 deletions(-) diff --git a/app/assets/javascripts/app/frontend/controllers/editor.js b/app/assets/javascripts/app/frontend/controllers/editor.js index 04252b04f..6a49ab1a1 100644 --- a/app/assets/javascripts/app/frontend/controllers/editor.js +++ b/app/assets/javascripts/app/frontend/controllers/editor.js @@ -18,8 +18,6 @@ angular.module('app.frontend') scope.$watch('ctrl.note', function(note, oldNote){ if(note) { ctrl.setNote(note, oldNote); - } else { - ctrl.note = {}; } }); } @@ -28,7 +26,6 @@ angular.module('app.frontend') .controller('EditorCtrl', function ($sce, $timeout, authManager, $rootScope, extensionManager, syncManager, modelManager) { window.addEventListener("message", function(event){ - // console.log("App received message:", event); if(event.data.status) { this.postNoteToExternalEditor(); } else { @@ -92,7 +89,6 @@ angular.module('app.frontend') this.editorForNote = function(note) { var editors = modelManager.itemsForContentType("SN|Editor"); for(var editor of editors) { - // console.log(editor.notes, editor.references); if(_.includes(editor.notes, note)) { return editor; } diff --git a/app/assets/javascripts/app/frontend/controllers/home.js b/app/assets/javascripts/app/frontend/controllers/home.js index 9ee571cb2..550827f6b 100644 --- a/app/assets/javascripts/app/frontend/controllers/home.js +++ b/app/assets/javascripts/app/frontend/controllers/home.js @@ -25,6 +25,7 @@ angular.module('app.frontend') } syncManager.loadLocalItems(function(items) { + $scope.allTag.didLoad = true; $scope.$apply(); syncManager.sync(null); @@ -35,10 +36,11 @@ angular.module('app.frontend') }); var allTag = new Tag({all: true}); - allTag.title = "All"; - $scope.tags = modelManager.tags; - allTag.notes = modelManager.notes; + allTag.needsLoad = true; $scope.allTag = allTag; + $scope.allTag.title = "All"; + $scope.tags = modelManager.tags; + $scope.allTag.notes = modelManager.notes; /* Editor Callbacks diff --git a/app/assets/javascripts/app/frontend/controllers/notes.js b/app/assets/javascripts/app/frontend/controllers/notes.js index 9f7b13fa4..0ddf86061 100644 --- a/app/assets/javascripts/app/frontend/controllers/notes.js +++ b/app/assets/javascripts/app/frontend/controllers/notes.js @@ -18,7 +18,16 @@ angular.module('app.frontend') link:function(scope, elem, attrs, ctrl) { scope.$watch('ctrl.tag', function(tag, oldTag){ if(tag) { - ctrl.tagDidChange(tag, oldTag); + if(tag.needsLoad) { + scope.$watch('ctrl.tag.didLoad', function(didLoad){ + if(didLoad) { + tag.needsLoad = false; + ctrl.tagDidChange(tag, oldTag); + } + }); + } else { + ctrl.tagDidChange(tag, oldTag); + } } }); } @@ -45,12 +54,15 @@ angular.module('app.frontend') } this.noteFilter.text = ""; + this.setNotes(tag.notes); + } - tag.notes.forEach(function(note){ + this.setNotes = function(notes) { + notes.forEach(function(note){ note.visible = true; }) - var createNew = tag.notes.length == 0; + var createNew = notes.length == 0; this.selectFirstNote(createNew); } diff --git a/app/assets/templates/frontend/editor.html.haml b/app/assets/templates/frontend/editor.html.haml index ee505a48d..933e00c99 100644 --- a/app/assets/templates/frontend/editor.html.haml +++ b/app/assets/templates/frontend/editor.html.haml @@ -1,5 +1,5 @@ .section.editor{"ng-class" => "{'fullscreen' : ctrl.fullscreen}"} - .section-title-bar.editor-heading{"ng-class" => "{'fullscreen' : ctrl.fullscreen }"} + .section-title-bar.editor-heading{"ng-if" => "ctrl.note", "ng-class" => "{'fullscreen' : ctrl.fullscreen }"} .title %input.input#note-title-editor{"ng-model" => "ctrl.note.title", "ng-keyup" => "$event.keyCode == 13 && ctrl.saveTitle($event)", "ng-change" => "ctrl.nameChanged()", "ng-focus" => "ctrl.onNameFocus()", @@ -8,7 +8,7 @@ .tags %input.tags-input{"type" => "text", "ng-keyup" => "$event.keyCode == 13 && $event.target.blur();", "ng-model" => "ctrl.tagsString", "placeholder" => "#tags", "ng-blur" => "ctrl.updateTagsFromTagsString($event, ctrl.tagsString)"} - .section-menu + .section-menu{"ng-if" => "ctrl.note"} %ul.nav %li.dropdown.pull-left.mr-10{"click-outside" => "ctrl.showMenu = false;", "is-open" => "ctrl.showMenu"} %a.dropdown-toggle{"ng-click" => "ctrl.showMenu = !ctrl.showMenu; ctrl.showExtensions = false;"} @@ -20,7 +20,7 @@ %li{"ng-click" => "ctrl.selectedMenuItem(); ctrl.toggleFullScreen()"} .text Toggle Fullscreen %li{"ng-click" => "ctrl.deleteNote()"} - .text Delete + .text Delete Note %li.sep %li.dropdown.pull-left.mr-10{"click-outside" => "ctrl.showEditorMenu = false;", "is-open" => "ctrl.showEditorMenu"} diff --git a/app/assets/templates/frontend/home.html.haml b/app/assets/templates/frontend/home.html.haml index 82642f6f9..61203afcd 100644 --- a/app/assets/templates/frontend/home.html.haml +++ b/app/assets/templates/frontend/home.html.haml @@ -6,6 +6,6 @@ %notes-section{"remove-tag" => "notesRemoveTag", "add-new" => "notesAddNew", "selection-made" => "notesSelectionMade", "tag" => "selectedTag", "remove" => "deleteNote"} - %editor-section{"ng-if" => "selectedNote", "note" => "selectedNote", "remove" => "deleteNote", "save" => "saveNote", "update-tags" => "updateTagsForNote"} + %editor-section{"note" => "selectedNote", "remove" => "deleteNote", "save" => "saveNote", "update-tags" => "updateTagsForNote"} %header diff --git a/app/assets/templates/frontend/notes.html.haml b/app/assets/templates/frontend/notes.html.haml index e6869f2d6..63a42b7f0 100644 --- a/app/assets/templates/frontend/notes.html.haml +++ b/app/assets/templates/frontend/notes.html.haml @@ -15,8 +15,6 @@ %span.sr-only %ul.dropdown-menu.dropdown-menu-left.nt-dropdown-menu.dark{"ng-if" => "ctrl.showMenu"} - %li - %a.text{"ng-click" => "ctrl.selectedMenuItem(); ctrl.selectedTagDelete()"} Delete Tag %li %a.text{"ng-click" => "ctrl.selectedMenuItem(); ctrl.selectedSortByCreated()"} %span.top.mt-5.mr-5{"ng-if" => "ctrl.sortBy == 'created_at'"} ✓ @@ -25,6 +23,8 @@ %a.text{"ng-click" => "ctrl.selectedMenuItem(); ctrl.selectedSortByUpdated()"} %span.top.mt-5.mr-5{"ng-if" => "ctrl.sortBy == 'updated_at'"} ✓ Sort by date updated + %li + %a.text{"ng-click" => "ctrl.selectedMenuItem(); ctrl.selectedTagDelete()"} Delete Tag .scrollable .infinite-scroll{"infinite-scroll" => "ctrl.paginate()", "can-load" => "true", "threshold" => "200"} From 4dc2cfffb7b84ff0cd39680c38eb05aaa224aefc Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Tue, 28 Feb 2017 09:24:59 -0600 Subject: [PATCH 12/16] add data check for editor --- app/assets/javascripts/app/frontend/models/app/editor.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/assets/javascripts/app/frontend/models/app/editor.js b/app/assets/javascripts/app/frontend/models/app/editor.js index 49e84666d..00a09cc0f 100644 --- a/app/assets/javascripts/app/frontend/models/app/editor.js +++ b/app/assets/javascripts/app/frontend/models/app/editor.js @@ -5,6 +5,9 @@ class Editor extends Item { if(!this.notes) { this.notes = []; } + if(!this.data) { + this.data = {}; + } } mapContentToLocalProperties(contentObject) { From 19967577080088e2341635f8bacf92a7513b17ee Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Tue, 28 Feb 2017 11:09:47 -0600 Subject: [PATCH 13/16] editor change fixes --- .../app/frontend/controllers/editor.js | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/app/frontend/controllers/editor.js b/app/assets/javascripts/app/frontend/controllers/editor.js index 6a49ab1a1..b57f2e1ea 100644 --- a/app/assets/javascripts/app/frontend/controllers/editor.js +++ b/app/assets/javascripts/app/frontend/controllers/editor.js @@ -35,9 +35,11 @@ angular.module('app.frontend') if(this.note.uuid === id) { this.note.text = text; - var changesMade = this.customEditor.setData(id, data); - if(changesMade) { - this.customEditor.setDirty(true); + if(data) { + var changesMade = this.customEditor.setData(id, data); + if(changesMade) { + this.customEditor.setDirty(true); + } } this.changesMade(); } @@ -45,15 +47,28 @@ angular.module('app.frontend') }.bind(this), false); this.setNote = function(note, oldNote) { + var currentEditor = this.customEditor; + this.customEditor = null; this.showExtensions = false; this.showMenu = false; this.loadTagsString(); - var editor = this.editorForNote(note); - - if(editor) { + var setEditor = function(editor) { this.customEditor = editor; this.postNoteToExternalEditor(); + }.bind(this) + + var editor = this.editorForNote(note); + if(editor) { + if(currentEditor !== editor) { + // switch after timeout, so that note data isnt posted to current editor + $timeout(function(){ + setEditor(editor); + }.bind(this)); + } else { + // switch immediately + setEditor(editor); + } } else { this.customEditor = null; } @@ -73,11 +88,13 @@ angular.module('app.frontend') this.selectedEditor = function(editor) { this.showEditorMenu = false; + + if(this.customEditor && editor !== this.customEditor) { + this.customEditor.removeItemAsRelationship(this.note); + this.customEditor.setDirty(true); + } + if(editor.default) { - if(this.customEditor) { - this.customEditor.removeItemAsRelationship(this.note); - this.customEditor.setDirty(true); - } this.customEditor = null; } else { this.customEditor = editor; From 3b69a7d211c2ee7b9c6266ee21bd38d10a05f664 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 1 Mar 2017 16:58:46 -0600 Subject: [PATCH 14/16] adds merge local, closes #71 --- .../services/directives/views/accountMenu.js | 30 ++++++++++++++++--- .../directives/account-menu.html.haml | 6 +++- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/app/services/directives/views/accountMenu.js b/app/assets/javascripts/app/services/directives/views/accountMenu.js index 4b2046284..3d52a9af8 100644 --- a/app/assets/javascripts/app/services/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/services/directives/views/accountMenu.js @@ -6,10 +6,10 @@ class AccountMenu { this.scope = {}; } - controller($scope, authManager, modelManager, syncManager, $timeout) { + controller($scope, authManager, modelManager, syncManager, dbManager, $timeout) { 'ngInject'; - $scope.formData = {url: syncManager.serverURL}; + $scope.formData = {mergeLocal: true, url: syncManager.serverURL}; $scope.user = authManager.user; $scope.server = syncManager.serverURL; @@ -113,10 +113,32 @@ class AccountMenu { }) } + $scope.localNotesCount = function() { + return modelManager.filteredNotes.length; + } + + $scope.mergeLocalChanged = function() { + if(!$scope.formData.mergeLocal) { + if(!confirm("Unchecking this option means any of the notes you have written while you were signed out will be deleted. Are you sure you want to discard these notes?")) { + $scope.formData.mergeLocal = true; + } + } + } + $scope.onAuthSuccess = function() { - syncManager.markAllItemsDirtyAndSaveOffline(function(){ + var block = function() { window.location.reload(); - }) + } + + if($scope.formData.mergeLocal) { + syncManager.markAllItemsDirtyAndSaveOffline(function(){ + block(); + }) + } else { + dbManager.clearAllItems(function(){ + block(); + }) + } } $scope.destroyLocalData = function() { diff --git a/app/assets/templates/frontend/directives/account-menu.html.haml b/app/assets/templates/frontend/directives/account-menu.html.haml index 6927bff0f..3c93889a5 100644 --- a/app/assets/templates/frontend/directives/account-menu.html.haml +++ b/app/assets/templates/frontend/directives/account-menu.html.haml @@ -8,6 +8,10 @@ %input.form-control{:name => 'server', :placeholder => 'Server URL', :required => true, :type => 'text', 'ng-model' => 'formData.url'} %input.form-control{:autofocus => 'autofocus', :name => 'email', :placeholder => 'Email', :required => true, :type => 'email', 'ng-model' => 'formData.email'} %input.form-control{:placeholder => 'Password', :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.user_password'} + .checkbox{"ng-if" => "localNotesCount() > 0"} + %label + %input{"type" => "checkbox", "ng-model" => "formData.mergeLocal", "ng-bind" => "true", "ng-change" => "mergeLocalChanged()"} + Merge local notes ({{localNotesCount()}} notes) %div{"ng-if" => "!formData.status"} %button.btn.dark-button.half-button{"ng-click" => "loginSubmitPressed()", "data-style" => "expand-right", "data-size" => "s", "state" => "buttonState"} @@ -94,4 +98,4 @@ .spinner.mt-10{"ng-if" => "importData.loading"} - %a.block.mt-25.red{"ng-click" => "destroyLocalData()"} Destroy all local data + %a.block.mt-25.red{"ng-click" => "destroyLocalData()"} {{ user ? "Sign out and clear local data" : "Clear all local data" }} From 052c6a9cde4c3fd826edc002145166ee0f0d7c76 Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 1 Mar 2017 17:07:18 -0600 Subject: [PATCH 15/16] password confirmation on registration, closes #68 --- .../javascripts/app/services/directives/views/accountMenu.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/assets/javascripts/app/services/directives/views/accountMenu.js b/app/assets/javascripts/app/services/directives/views/accountMenu.js index 3d52a9af8..7fd9ca4c1 100644 --- a/app/assets/javascripts/app/services/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/services/directives/views/accountMenu.js @@ -98,6 +98,11 @@ class AccountMenu { } $scope.submitRegistrationForm = function() { + var confirmation = prompt("Please confirm your password. Note that because your notes are encrypted using your password, Standard Notes does not have a password reset option. You cannot forget your password.") + if(confirmation !== $scope.formData.user_password) { + alert("The two passwords you entered do not match. Please try again."); + return; + } $scope.formData.status = "Generating Account Keys..."; $timeout(function(){ From f7f0522f70c25382bd9991f68af63a50db4e2a2d Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Wed, 1 Mar 2017 17:44:20 -0600 Subject: [PATCH 16/16] fix on note delete, select first --- .../javascripts/app/frontend/controllers/editor.js | 7 ------- .../javascripts/app/frontend/controllers/home.js | 10 ++++++++++ .../javascripts/app/frontend/controllers/notes.js | 1 - app/assets/javascripts/app/services/authManager.js | 2 +- app/assets/templates/frontend/home.html.haml | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/app/frontend/controllers/editor.js b/app/assets/javascripts/app/frontend/controllers/editor.js index c9e8c9016..cdca7863e 100644 --- a/app/assets/javascripts/app/frontend/controllers/editor.js +++ b/app/assets/javascripts/app/frontend/controllers/editor.js @@ -224,16 +224,9 @@ angular.module('app.frontend') if(confirm("Are you sure you want to delete this note?")) { this.remove()(this.note); this.showMenu = false; - this.notifyDelete(); } } - this.notifyDelete = function() { - $timeout(function() { - $rootScope.$broadcast("noteDeleted"); - }.bind(this), 500); - } - this.clickedEditNote = function() { this.editorMode = 'edit'; this.focusEditor(100); diff --git a/app/assets/javascripts/app/frontend/controllers/home.js b/app/assets/javascripts/app/frontend/controllers/home.js index 550827f6b..df1f9307f 100644 --- a/app/assets/javascripts/app/frontend/controllers/home.js +++ b/app/assets/javascripts/app/frontend/controllers/home.js @@ -153,6 +153,12 @@ angular.module('app.frontend') this.$apply(fn); }; + $scope.notifyDelete = function() { + $timeout(function() { + $rootScope.$broadcast("noteDeleted"); + }.bind(this), 0); + } + $scope.deleteNote = function(note) { modelManager.setItemToBeDeleted(note); @@ -163,6 +169,7 @@ angular.module('app.frontend') if(note.dummy) { modelManager.removeItemLocally(note); + $scope.notifyDelete(); return; } @@ -170,8 +177,11 @@ angular.module('app.frontend') if(authManager.offline()) { // when deleting items while ofline, we need to explictly tell angular to refresh UI setTimeout(function () { + $scope.notifyDelete(); $scope.safeApply(); }, 50); + } else { + $scope.notifyDelete(); } }); } diff --git a/app/assets/javascripts/app/frontend/controllers/notes.js b/app/assets/javascripts/app/frontend/controllers/notes.js index 579d3e1d0..0d3106260 100644 --- a/app/assets/javascripts/app/frontend/controllers/notes.js +++ b/app/assets/javascripts/app/frontend/controllers/notes.js @@ -4,7 +4,6 @@ angular.module('app.frontend') scope: { addNew: "&", selectionMade: "&", - remove: "&", tag: "=", removeTag: "&" }, diff --git a/app/assets/javascripts/app/services/authManager.js b/app/assets/javascripts/app/services/authManager.js index 5a9d1bde2..b0bb0a9b4 100644 --- a/app/assets/javascripts/app/services/authManager.js +++ b/app/assets/javascripts/app/services/authManager.js @@ -112,7 +112,7 @@ angular.module('app.frontend') }.bind(this)) .catch(function(response){ console.log("Registration error", response); - callback(null); + callback(response.data); }) }.bind(this)); } diff --git a/app/assets/templates/frontend/home.html.haml b/app/assets/templates/frontend/home.html.haml index 61203afcd..28584401b 100644 --- a/app/assets/templates/frontend/home.html.haml +++ b/app/assets/templates/frontend/home.html.haml @@ -4,7 +4,7 @@ "tags" => "tags"} %notes-section{"remove-tag" => "notesRemoveTag", "add-new" => "notesAddNew", "selection-made" => "notesSelectionMade", - "tag" => "selectedTag", "remove" => "deleteNote"} + "tag" => "selectedTag"} %editor-section{"note" => "selectedNote", "remove" => "deleteNote", "save" => "saveNote", "update-tags" => "updateTagsForNote"}