merged master
This commit is contained in:
@@ -15,30 +15,9 @@ 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);
|
||||
} else {
|
||||
ctrl.note = {};
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -47,27 +26,49 @@ 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 {
|
||||
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;
|
||||
if(data) {
|
||||
var changesMade = this.customEditor.setData(id, data);
|
||||
if(changesMade) {
|
||||
this.customEditor.setDirty(true);
|
||||
}
|
||||
}
|
||||
this.changesMade();
|
||||
}
|
||||
}
|
||||
}.bind(this), false);
|
||||
|
||||
this.setNote = function(note, oldNote) {
|
||||
var currentEditor = this.customEditor;
|
||||
this.customEditor = null;
|
||||
this.showExtensions = false;
|
||||
this.showMenu = false;
|
||||
this.loadTagsString();
|
||||
|
||||
if(note.editorUrl) {
|
||||
this.customEditor = this.editorForUrl(note.editorUrl);
|
||||
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;
|
||||
}
|
||||
@@ -87,23 +88,35 @@ 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) {
|
||||
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) {
|
||||
if(_.includes(editor.notes, note)) {
|
||||
return editor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
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}, '*');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,6 +227,11 @@ angular.module('app.frontend')
|
||||
}
|
||||
}
|
||||
|
||||
this.clickedEditNote = function() {
|
||||
this.editorMode = 'edit';
|
||||
this.focusEditor(100);
|
||||
}
|
||||
|
||||
/* Tags */
|
||||
|
||||
this.loadTagsString = function() {
|
||||
|
||||
@@ -1,7 +1,31 @@
|
||||
angular.module('app.frontend')
|
||||
.controller('HomeCtrl', function ($scope, $rootScope, $timeout, modelManager, syncManager, authManager) {
|
||||
.controller('HomeCtrl', function ($scope, $stateParams, $rootScope, $timeout, modelManager, syncManager, authManager) {
|
||||
|
||||
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) {
|
||||
$scope.allTag.didLoad = true;
|
||||
$scope.$apply();
|
||||
|
||||
syncManager.sync(null);
|
||||
@@ -11,7 +35,9 @@ angular.module('app.frontend')
|
||||
}, 30000);
|
||||
});
|
||||
|
||||
$scope.allTag = new Tag({all: true});
|
||||
var allTag = new Tag({all: true});
|
||||
allTag.needsLoad = true;
|
||||
$scope.allTag = allTag;
|
||||
$scope.allTag.title = "All";
|
||||
$scope.tags = modelManager.tags;
|
||||
$scope.allTag.notes = modelManager.notes;
|
||||
@@ -127,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);
|
||||
@@ -137,6 +169,7 @@ angular.module('app.frontend')
|
||||
|
||||
if(note.dummy) {
|
||||
modelManager.removeItemLocally(note);
|
||||
$scope.notifyDelete();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -144,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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ angular.module('app.frontend')
|
||||
scope: {
|
||||
addNew: "&",
|
||||
selectionMade: "&",
|
||||
remove: "&",
|
||||
tag: "=",
|
||||
removeTag: "&"
|
||||
},
|
||||
@@ -18,7 +17,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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -32,7 +40,9 @@ angular.module('app.frontend')
|
||||
this.showMenu = false;
|
||||
}.bind(this))
|
||||
|
||||
var isFirstLoad = true;
|
||||
$rootScope.$on("noteDeleted", function() {
|
||||
this.selectFirstNote(false);
|
||||
}.bind(this))
|
||||
|
||||
this.notesToDisplay = 20;
|
||||
this.paginate = function() {
|
||||
@@ -47,20 +57,16 @@ 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;
|
||||
})
|
||||
this.selectFirstNote(false);
|
||||
|
||||
if(isFirstLoad) {
|
||||
$timeout(function(){
|
||||
this.createNewNote();
|
||||
isFirstLoad = false;
|
||||
}.bind(this))
|
||||
} else if(tag.notes.length == 0) {
|
||||
this.createNewNote();
|
||||
}
|
||||
var createNew = notes.length == 0;
|
||||
this.selectFirstNote(createNew);
|
||||
}
|
||||
|
||||
this.selectedTagDelete = function() {
|
||||
@@ -69,7 +75,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;
|
||||
});
|
||||
|
||||
|
||||
@@ -2,24 +2,70 @@ class Editor extends Item {
|
||||
|
||||
constructor(json_obj) {
|
||||
super(json_obj);
|
||||
if(!this.notes) {
|
||||
this.notes = [];
|
||||
}
|
||||
if(!this.data) {
|
||||
this.data = {};
|
||||
}
|
||||
}
|
||||
|
||||
mapContentToLocalProperties(contentObject) {
|
||||
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());
|
||||
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}
|
||||
}
|
||||
@@ -27,4 +73,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] || {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ class Note extends Item {
|
||||
_.pull(tag.notes, this);
|
||||
}.bind(this))
|
||||
this.tags = [];
|
||||
}
|
||||
}
|
||||
|
||||
isBeingRemovedLocally() {
|
||||
this.tags.forEach(function(tag){
|
||||
|
||||
@@ -16,7 +16,7 @@ class ItemParams {
|
||||
}
|
||||
|
||||
paramsForLocalStorage() {
|
||||
this.additionalFields = ["updated_at", "dirty", "editorUrl"];
|
||||
this.additionalFields = ["updated_at", "dirty"];
|
||||
this.forExportFile = true;
|
||||
return this.__params();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ angular.module('app.frontend')
|
||||
})
|
||||
|
||||
.state('home', {
|
||||
url: '/',
|
||||
url: '/?server&email&pw',
|
||||
parent: 'base',
|
||||
views: {
|
||||
'content@' : {
|
||||
|
||||
@@ -78,7 +78,7 @@ angular.module('app.frontend')
|
||||
callback(response);
|
||||
}.bind(this), function(response){
|
||||
console.error("Error logging in", response);
|
||||
callback(null);
|
||||
callback(response);
|
||||
})
|
||||
|
||||
}.bind(this));
|
||||
@@ -106,8 +106,8 @@ angular.module('app.frontend')
|
||||
callback(response);
|
||||
}.bind(this), function(response){
|
||||
console.error("Registration error", response);
|
||||
callback(null);
|
||||
})
|
||||
callback(response);
|
||||
}.bind(this))
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ angular.module('app.frontend')
|
||||
this.handleAuthResponse(response, email, null, authParams, keys.mk, keys.pw);
|
||||
callback(response);
|
||||
}.bind(this), function(response){
|
||||
var error = response.data;
|
||||
var error = response;
|
||||
if(!error) {
|
||||
error = {message: "Something went wrong while changing your password. Your password was not changed. Please try again."}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
@@ -99,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(){
|
||||
@@ -114,10 +118,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() {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -213,7 +212,7 @@ class SyncManager {
|
||||
|
||||
}.bind(this), function(response){
|
||||
console.log("Sync error: ", response);
|
||||
var error = response.data ? response.data.error : {message: "Could not connect to server."};
|
||||
var error = response ? response.error : {message: "Could not connect to server."};
|
||||
|
||||
this.syncStatus.syncOpInProgress = false;
|
||||
this.syncStatus.error = error;
|
||||
|
||||
@@ -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" }}
|
||||
|
||||
@@ -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,20 +8,19 @@
|
||||
.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;"}
|
||||
File
|
||||
Menu
|
||||
%span.caret
|
||||
%span.sr-only
|
||||
|
||||
%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
|
||||
.text Delete Note
|
||||
|
||||
%li.sep
|
||||
%li.dropdown.pull-left.mr-10{"click-outside" => "ctrl.showEditorMenu = false;", "is-open" => "ctrl.showEditorMenu"}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"tags" => "tags"}
|
||||
|
||||
%notes-section{"remove-tag" => "notesRemoveTag", "add-new" => "notesAddNew", "selection-made" => "notesSelectionMade",
|
||||
"tag" => "selectedTag", "remove" => "deleteNote"}
|
||||
"tag" => "selectedTag"}
|
||||
|
||||
%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
|
||||
|
||||
@@ -10,13 +10,11 @@
|
||||
%ul.nav.nav-pills
|
||||
%li.dropdown
|
||||
%a.dropdown-toggle{"ng-click" => "ctrl.showMenu = !ctrl.showMenu"}
|
||||
Tag options
|
||||
Menu
|
||||
%span.caret
|
||||
%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,10 +23,12 @@
|
||||
%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"}
|
||||
.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}}
|
||||
|
||||
@@ -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?
|
||||
|
||||
Reference in New Issue
Block a user