model manager refactor
This commit is contained in:
@@ -63,12 +63,12 @@ angular.module('app.frontend')
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.controller('EditorCtrl', function ($sce, $timeout, apiController, modelManager, markdownRenderer, $rootScope) {
|
.controller('EditorCtrl', function ($sce, $timeout, apiController, markdownRenderer, $rootScope) {
|
||||||
|
|
||||||
this.setNote = function(note, oldNote) {
|
this.setNote = function(note, oldNote) {
|
||||||
this.editorMode = 'edit';
|
this.editorMode = 'edit';
|
||||||
|
|
||||||
if(note.content.text.length == 0 && note.dummy) {
|
if(note.safeText().length == 0 && note.dummy) {
|
||||||
this.focusTitle(100);
|
this.focusTitle(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ angular.module('app.frontend')
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.renderedContent = function() {
|
this.renderedContent = function() {
|
||||||
return markdownRenderer.renderHtml(markdownRenderer.renderedContentForText(this.note.content.text));
|
return markdownRenderer.renderHtml(markdownRenderer.renderedContentForText(this.note.safeText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
var statusTimeout;
|
var statusTimeout;
|
||||||
@@ -207,7 +207,7 @@ angular.module('app.frontend')
|
|||||||
|
|
||||||
var original = this.note.presentation_name;
|
var original = this.note.presentation_name;
|
||||||
this.note.presentation_name = this.url.token;
|
this.note.presentation_name = this.url.token;
|
||||||
modelManager.addDirtyItems([this.note]);
|
this.note.dirty = true;
|
||||||
|
|
||||||
apiController.sync(function(response){
|
apiController.sync(function(response){
|
||||||
if(!response) {
|
if(!response) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ angular.module('app.frontend')
|
|||||||
var onUserSet = function() {
|
var onUserSet = function() {
|
||||||
apiController.setUser($scope.defaultUser);
|
apiController.setUser($scope.defaultUser);
|
||||||
$scope.allTag = new Tag({all: true});
|
$scope.allTag = new Tag({all: true});
|
||||||
$scope.allTag.content.title = "All";
|
$scope.allTag.title = "All";
|
||||||
$scope.tags = modelManager.tags;
|
$scope.tags = modelManager.tags;
|
||||||
$scope.allTag.notes = modelManager.notes;
|
$scope.allTag.notes = modelManager.notes;
|
||||||
|
|
||||||
@@ -43,14 +43,18 @@ angular.module('app.frontend')
|
|||||||
|
|
||||||
$scope.tagsSelectionMade = function(tag) {
|
$scope.tagsSelectionMade = function(tag) {
|
||||||
$scope.selectedTag = tag;
|
$scope.selectedTag = tag;
|
||||||
|
|
||||||
|
if($scope.selectedNote && $scope.selectedNote.dummy) {
|
||||||
|
modelManager.removeItemLocally($scope.selectedNote);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.tagsAddNew = function(tag) {
|
$scope.tagsAddNew = function(tag) {
|
||||||
modelManager.addTag(tag);
|
modelManager.addItem(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.tagsSave = function(tag, callback) {
|
$scope.tagsSave = function(tag, callback) {
|
||||||
modelManager.addDirtyItems([tag]);
|
tag.dirty = true;
|
||||||
apiController.sync(callback);
|
apiController.sync(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +66,7 @@ angular.module('app.frontend')
|
|||||||
|
|
||||||
var originalNote = _.find(modelManager.notes, {uuid: noteCopy.uuid});
|
var originalNote = _.find(modelManager.notes, {uuid: noteCopy.uuid});
|
||||||
if(!newTag.all) {
|
if(!newTag.all) {
|
||||||
modelManager.addTagToNote(newTag, originalNote);
|
modelManager.createRelationshipBetweenItems(newTag, originalNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
apiController.sync(function(){});
|
apiController.sync(function(){});
|
||||||
@@ -75,9 +79,9 @@ angular.module('app.frontend')
|
|||||||
$scope.notesRemoveTag = function(tag) {
|
$scope.notesRemoveTag = function(tag) {
|
||||||
var validNotes = Note.filterDummyNotes(tag.notes);
|
var validNotes = Note.filterDummyNotes(tag.notes);
|
||||||
if(validNotes == 0) {
|
if(validNotes == 0) {
|
||||||
modelManager.deleteTag(tag);
|
modelManager.setItemToBeDeleted(tag);
|
||||||
// if no more notes, delete tag
|
// if no more notes, delete tag
|
||||||
apiController.deleteItem(tag, function(){
|
apiController.sync(function(){
|
||||||
// force scope tags to update on sub directives
|
// force scope tags to update on sub directives
|
||||||
$scope.tags = [];
|
$scope.tags = [];
|
||||||
$timeout(function(){
|
$timeout(function(){
|
||||||
@@ -94,10 +98,10 @@ angular.module('app.frontend')
|
|||||||
}
|
}
|
||||||
|
|
||||||
$scope.notesAddNew = function(note) {
|
$scope.notesAddNew = function(note) {
|
||||||
modelManager.addNote(note);
|
modelManager.addItem(note);
|
||||||
|
|
||||||
if(!$scope.selectedTag.all) {
|
if(!$scope.selectedTag.all) {
|
||||||
modelManager.addTagToNote($scope.selectedTag, note);
|
modelManager.createRelationshipBetweenItems($scope.selectedTag, note);
|
||||||
$scope.updateAllTag();
|
$scope.updateAllTag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +111,7 @@ angular.module('app.frontend')
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
$scope.saveNote = function(note, callback) {
|
$scope.saveNote = function(note, callback) {
|
||||||
modelManager.addDirtyItems(note);
|
note.dirty = true;
|
||||||
|
|
||||||
apiController.sync(function(){
|
apiController.sync(function(){
|
||||||
note.hasChanges = false;
|
note.hasChanges = false;
|
||||||
@@ -120,17 +124,18 @@ angular.module('app.frontend')
|
|||||||
|
|
||||||
$scope.deleteNote = function(note) {
|
$scope.deleteNote = function(note) {
|
||||||
|
|
||||||
modelManager.deleteNote(note);
|
modelManager.setItemToBeDeleted(note);
|
||||||
|
|
||||||
if(note == $scope.selectedNote) {
|
if(note == $scope.selectedNote) {
|
||||||
$scope.selectedNote = null;
|
$scope.selectedNote = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(note.dummy) {
|
if(note.dummy) {
|
||||||
|
modelManager.removeItemLocally(note);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
apiController.deleteItem(note, function(success){})
|
apiController.sync(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -110,8 +110,8 @@ angular.module('app.frontend')
|
|||||||
|
|
||||||
this.createNewNote = function() {
|
this.createNewNote = function() {
|
||||||
var title = "New Note" + (this.tag.notes ? (" " + (this.tag.notes.length + 1)) : "");
|
var title = "New Note" + (this.tag.notes ? (" " + (this.tag.notes.length + 1)) : "");
|
||||||
this.newNote = new Note({dummy: true});
|
this.newNote = new Note({dummy: true, text: ""});
|
||||||
this.newNote.content.title = title;
|
this.newNote.title = title;
|
||||||
this.selectNote(this.newNote);
|
this.selectNote(this.newNote);
|
||||||
this.addNew()(this.newNote);
|
this.addNew()(this.newNote);
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ angular.module('app.frontend')
|
|||||||
if(this.noteFilter.text.length == 0) {
|
if(this.noteFilter.text.length == 0) {
|
||||||
note.visible = true;
|
note.visible = true;
|
||||||
} else {
|
} else {
|
||||||
note.visible = note.content.title.toLowerCase().includes(this.noteFilter.text) || note.content.text.toLowerCase().includes(this.noteFilter.text);
|
note.visible = note.title.toLowerCase().includes(this.noteFilter.text) || note.text.toLowerCase().includes(this.noteFilter.text);
|
||||||
}
|
}
|
||||||
return note.visible;
|
return note.visible;
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ angular.module('app.frontend')
|
|||||||
if(this.editingTag) {
|
if(this.editingTag) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.newTag = new Tag();
|
this.newTag = new Tag({});
|
||||||
this.selectedTag = this.newTag;
|
this.selectedTag = this.newTag;
|
||||||
this.editingTag = this.newTag;
|
this.editingTag = this.newTag;
|
||||||
this.addNew()(this.newTag);
|
this.addNew()(this.newTag);
|
||||||
@@ -71,7 +71,7 @@ angular.module('app.frontend')
|
|||||||
|
|
||||||
var originalTagName = "";
|
var originalTagName = "";
|
||||||
this.onTagTitleFocus = function(tag) {
|
this.onTagTitleFocus = function(tag) {
|
||||||
originalTagName = tag.content.title;
|
originalTagName = tag.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.tagTitleDidChange = function(tag) {
|
this.tagTitleDidChange = function(tag) {
|
||||||
@@ -80,14 +80,14 @@ angular.module('app.frontend')
|
|||||||
|
|
||||||
this.saveTag = function($event, tag) {
|
this.saveTag = function($event, tag) {
|
||||||
this.editingTag = null;
|
this.editingTag = null;
|
||||||
if(tag.content.title.length == 0) {
|
if(tag.title.length == 0) {
|
||||||
tag.content.title = originalTagName;
|
tag.title = originalTagName;
|
||||||
originalTagName = "";
|
originalTagName = "";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$event.target.blur();
|
$event.target.blur();
|
||||||
if(!tag.content.title || tag.content.title.length == 0) {
|
if(!tag.title || tag.title.length == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,54 +1,12 @@
|
|||||||
class Item {
|
class Item {
|
||||||
|
|
||||||
constructor(json_obj) {
|
constructor(json_obj) {
|
||||||
|
|
||||||
var content;
|
this.updateFromJSON(json_obj);
|
||||||
|
|
||||||
Object.defineProperty(this, "content", {
|
|
||||||
get: function() {
|
|
||||||
return content;
|
|
||||||
},
|
|
||||||
set: function(value) {
|
|
||||||
var finalValue = value;
|
|
||||||
|
|
||||||
if(typeof value === 'string') {
|
|
||||||
try {
|
|
||||||
var decodedValue = JSON.parse(value);
|
|
||||||
finalValue = decodedValue;
|
|
||||||
}
|
|
||||||
catch(e) {
|
|
||||||
finalValue = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
content = finalValue;
|
|
||||||
},
|
|
||||||
enumerable: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
_.merge(this, json_obj);
|
|
||||||
|
|
||||||
if(this.created_at) {
|
|
||||||
this.created_at = new Date(this.created_at);
|
|
||||||
this.updated_at = new Date(this.updated_at);
|
|
||||||
} else {
|
|
||||||
this.created_at = new Date();
|
|
||||||
this.updated_at = new Date();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this.uuid) {
|
if(!this.uuid) {
|
||||||
this.uuid = Neeto.crypto.generateUUID();
|
this.uuid = Neeto.crypto.generateUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setContentRaw = function(rawContent) {
|
|
||||||
content = rawContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this.content) {
|
|
||||||
this.content = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this.content.references) {
|
|
||||||
this.content.references = [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static sortItemsByDate(items) {
|
static sortItemsByDate(items) {
|
||||||
@@ -57,31 +15,67 @@ class Item {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addReference(reference) {
|
get contentObject() {
|
||||||
this.content.references.push(reference);
|
// console.log("getting content object from content", this.content);
|
||||||
this.content.references = _.uniq(this.content.references);
|
if(!this.content) {
|
||||||
this.updateReferencesLocalMapping();
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.content !== null && typeof this.content === 'object') {
|
||||||
|
// this is the case when mapping localStorage content, in which case the content is already parsed
|
||||||
|
return this.content;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.parse(this.content);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeReference(reference) {
|
updateFromJSON(json) {
|
||||||
_.remove(this.content.references, _.find(this.content.references, {uuid: reference.uuid}));
|
_.merge(this, json);
|
||||||
this.updateReferencesLocalMapping();
|
if(this.created_at) {
|
||||||
|
this.created_at = new Date(this.created_at);
|
||||||
|
this.updated_at = new Date(this.updated_at);
|
||||||
|
} else {
|
||||||
|
this.created_at = new Date();
|
||||||
|
this.updated_at = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(json.content) {
|
||||||
|
this.mapContentToLocalProperties(this.contentObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
referencesMatchingContentType(contentType) {
|
mapContentToLocalProperties(contentObj) {
|
||||||
return this.content.references.filter(function(reference){
|
|
||||||
return reference.content_type == contentType;
|
}
|
||||||
});
|
|
||||||
|
createContentJSONFromProperties() {
|
||||||
|
return this.structureParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
referenceParams() {
|
||||||
|
// must override
|
||||||
|
}
|
||||||
|
|
||||||
|
structureParams() {
|
||||||
|
return {references: this.referenceParams()}
|
||||||
|
}
|
||||||
|
|
||||||
|
addItemAsRelationship(item) {
|
||||||
|
// must override
|
||||||
|
}
|
||||||
|
|
||||||
|
removeItemAsRelationship(item) {
|
||||||
|
// must override
|
||||||
|
}
|
||||||
|
|
||||||
|
removeFromRelationships() {
|
||||||
|
// must override
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeMetadataFromItem(item) {
|
mergeMetadataFromItem(item) {
|
||||||
_.merge(this, _.omit(item, ["content"]));
|
_.merge(this, _.omit(item, ["content"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateReferencesLocalMapping() {
|
|
||||||
// should be overriden to manage local properties
|
|
||||||
}
|
|
||||||
|
|
||||||
referencesAffectedBySharingChange() {
|
referencesAffectedBySharingChange() {
|
||||||
// should be overriden to determine which references should be decrypted/encrypted
|
// should be overriden to determine which references should be decrypted/encrypted
|
||||||
return null;
|
return null;
|
||||||
@@ -92,7 +86,7 @@ class Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isEncrypted() {
|
isEncrypted() {
|
||||||
return this.encryptionEnabled() && typeof this.content === 'string' ? true : false;
|
return this.encryptionEnabled() && this.content.substring(0, 3) === '001' ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptionEnabled() {
|
encryptionEnabled() {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
class Extension extends Item {
|
class Extension extends Item {
|
||||||
constructor(json) {
|
constructor(json) {
|
||||||
|
super(json);
|
||||||
_.merge(this, json);
|
_.merge(this, json);
|
||||||
|
|
||||||
this.actions = this.actions.map(function(action){
|
this.actions = this.actions.map(function(action){
|
||||||
|
|||||||
@@ -6,14 +6,52 @@ class Note extends Item {
|
|||||||
if(!this.tags) {
|
if(!this.tags) {
|
||||||
this.tags = [];
|
this.tags = [];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!this.content.title) {
|
mapContentToLocalProperties(contentObject) {
|
||||||
this.content.title = "";
|
super.mapContentToLocalProperties(contentObject)
|
||||||
}
|
this.title = contentObject.title;
|
||||||
|
this.text = contentObject.text;
|
||||||
|
}
|
||||||
|
|
||||||
if(!this.content.text) {
|
referenceParams() {
|
||||||
this.content.text = "";
|
var references = _.map(this.tags, function(tag){
|
||||||
|
return {uuid: tag.uuid, content_type: tag.content_type};
|
||||||
|
})
|
||||||
|
return references;
|
||||||
|
}
|
||||||
|
|
||||||
|
structureParams() {
|
||||||
|
var params = {
|
||||||
|
title: this.title,
|
||||||
|
text: this.text
|
||||||
|
};
|
||||||
|
|
||||||
|
_.merge(params, super.structureParams());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
addItemAsRelationship(item) {
|
||||||
|
if(item.content_type == "Tag") {
|
||||||
|
if(!_.find(this.tags, item)) {
|
||||||
|
this.tags.push(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
super.addItemAsRelationship(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeItemAsRelationship(item) {
|
||||||
|
if(item.content_type == "Tag") {
|
||||||
|
_.pull(this.tags, item);
|
||||||
|
}
|
||||||
|
super.removeItemAsRelationship(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeFromRelationships() {
|
||||||
|
this.tags.forEach(function(tag){
|
||||||
|
_.pull(tag.notes, this);
|
||||||
|
tag.dirty = true;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static filterDummyNotes(notes) {
|
static filterDummyNotes(notes) {
|
||||||
@@ -21,11 +59,6 @@ class Note extends Item {
|
|||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateReferencesLocalMapping() {
|
|
||||||
super.updateReferencesLocalMapping();
|
|
||||||
this.tags = this.referencesMatchingContentType("Tag");
|
|
||||||
}
|
|
||||||
|
|
||||||
referencesAffectedBySharingChange() {
|
referencesAffectedBySharingChange() {
|
||||||
return super.referencesAffectedBySharingChange();
|
return super.referencesAffectedBySharingChange();
|
||||||
}
|
}
|
||||||
@@ -39,6 +72,14 @@ class Note extends Item {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
safeText() {
|
||||||
|
return this.text || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
safeTitle() {
|
||||||
|
return this.title || "";
|
||||||
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
return {uuid: this.uuid}
|
return {uuid: this.uuid}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,22 +6,57 @@ class Tag extends Item {
|
|||||||
if(!this.notes) {
|
if(!this.notes) {
|
||||||
this.notes = [];
|
this.notes = [];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!this.content.title) {
|
mapContentToLocalProperties(contentObject) {
|
||||||
this.content.title = "";
|
super.mapContentToLocalProperties(contentObject)
|
||||||
|
this.title = contentObject.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
referenceParams() {
|
||||||
|
var references = _.map(this.notes, function(note){
|
||||||
|
return {uuid: note.uuid, content_type: note.content_type};
|
||||||
|
})
|
||||||
|
return references;
|
||||||
|
}
|
||||||
|
|
||||||
|
structureParams() {
|
||||||
|
var params = {
|
||||||
|
title: this.title
|
||||||
|
};
|
||||||
|
|
||||||
|
_.merge(params, super.structureParams());
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
addItemAsRelationship(item) {
|
||||||
|
if(item.content_type == "Note") {
|
||||||
|
if(!_.find(this.notes, item)) {
|
||||||
|
this.notes.unshift(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
super.addItemAsRelationship(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeItemAsRelationship(item) {
|
||||||
|
if(item.content_type == "Note") {
|
||||||
|
_.pull(this.notes, item);
|
||||||
|
}
|
||||||
|
super.removeItemAsRelationship(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeFromRelationships() {
|
||||||
|
this.notes.forEach(function(note){
|
||||||
|
_.pull(note.tags, this);
|
||||||
|
note.dirty = true;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
get content_type() {
|
get content_type() {
|
||||||
return "Tag";
|
return "Tag";
|
||||||
}
|
}
|
||||||
|
|
||||||
updateReferencesLocalMapping() {
|
|
||||||
super.updateReferencesLocalMapping();
|
|
||||||
this.notes = this.referencesMatchingContentType("Note");
|
|
||||||
}
|
|
||||||
|
|
||||||
referencesAffectedBySharingChange() {
|
referencesAffectedBySharingChange() {
|
||||||
return this.referencesMatchingContentType("Note");
|
return this.notes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -218,20 +218,24 @@ angular.module('app.frontend')
|
|||||||
|
|
||||||
this.syncWithOptions = function(callback, options = {}) {
|
this.syncWithOptions = function(callback, options = {}) {
|
||||||
if(!this.user.uuid) {
|
if(!this.user.uuid) {
|
||||||
this.writeItemsToLocalStorage();
|
this.writeItemsToLocalStorage(function(responseItems){
|
||||||
modelManager.clearDirtyItems();
|
this.handleItemsResponse(responseItems);
|
||||||
if(callback) {
|
modelManager.clearDirtyItems();
|
||||||
callback();
|
if(callback) {
|
||||||
}
|
callback();
|
||||||
|
}
|
||||||
|
}.bind(this))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dirtyItems = modelManager.dirtyItems;
|
var dirtyItems = modelManager.getDirtyItems();
|
||||||
var request = Restangular.one("items/sync");
|
var request = Restangular.one("items/sync");
|
||||||
request.items = _.map(dirtyItems, function(item){
|
request.items = _.map(dirtyItems, function(item){
|
||||||
return this.createRequestParamsForItem(item, options.additionalFields);
|
return this.createRequestParamsForItem(item, options.additionalFields);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
|
console.log("syncing items", request.items);
|
||||||
|
|
||||||
if(this.syncToken) {
|
if(this.syncToken) {
|
||||||
request.sync_token = this.syncToken;
|
request.sync_token = this.syncToken;
|
||||||
}
|
}
|
||||||
@@ -272,11 +276,10 @@ angular.module('app.frontend')
|
|||||||
this.paramsForItem = function(item, encrypted, additionalFields, forExportFile) {
|
this.paramsForItem = function(item, encrypted, additionalFields, forExportFile) {
|
||||||
var itemCopy = _.cloneDeep(item);
|
var itemCopy = _.cloneDeep(item);
|
||||||
|
|
||||||
var params = {uuid: item.uuid, content_type: item.content_type, presentation_name: item.presentation_name, deleted: item.deleted};
|
console.assert(!item.dummy, "Item is dummy, should not have gotten here.", item.dummy)
|
||||||
|
|
||||||
itemCopy.content.references = _.map(itemCopy.content.references, function(reference){
|
var params = {uuid: item.uuid, content_type: item.content_type,
|
||||||
return {uuid: reference.uuid, content_type: reference.content_type};
|
presentation_name: item.presentation_name, deleted: item.deleted};
|
||||||
})
|
|
||||||
|
|
||||||
if(encrypted) {
|
if(encrypted) {
|
||||||
this.encryptSingleItem(itemCopy, this.retrieveMk());
|
this.encryptSingleItem(itemCopy, this.retrieveMk());
|
||||||
@@ -285,7 +288,7 @@ angular.module('app.frontend')
|
|||||||
params.auth_hash = itemCopy.auth_hash;
|
params.auth_hash = itemCopy.auth_hash;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
params.content = forExportFile ? itemCopy.content : "000" + Neeto.crypto.base64(JSON.stringify(itemCopy.content));
|
params.content = forExportFile ? itemCopy.content : "000" + Neeto.crypto.base64(JSON.stringify(itemCopy.createContentJSONFromProperties()));
|
||||||
if(!forExportFile) {
|
if(!forExportFile) {
|
||||||
params.enc_item_key = null;
|
params.enc_item_key = null;
|
||||||
params.auth_hash = null;
|
params.auth_hash = null;
|
||||||
@@ -299,13 +302,6 @@ angular.module('app.frontend')
|
|||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.deleteItem = function(item, callback) {
|
|
||||||
item.deleted = true;
|
|
||||||
modelManager.addDirtyItems([item]);
|
|
||||||
this.sync(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.shareItem = function(item, callback) {
|
this.shareItem = function(item, callback) {
|
||||||
if(!this.user.uuid) {
|
if(!this.user.uuid) {
|
||||||
alert("You must be signed in to share.");
|
alert("You must be signed in to share.");
|
||||||
@@ -315,7 +311,9 @@ angular.module('app.frontend')
|
|||||||
var shareFn = function() {
|
var shareFn = function() {
|
||||||
item.presentation_name = "_auto_";
|
item.presentation_name = "_auto_";
|
||||||
var needsUpdate = [item].concat(item.referencesAffectedBySharingChange() || []);
|
var needsUpdate = [item].concat(item.referencesAffectedBySharingChange() || []);
|
||||||
modelManager.addDirtyItems(needsUpdate);
|
needsUpdate.forEach(function(needingUpdate){
|
||||||
|
needingUpdate.dirty = true;
|
||||||
|
})
|
||||||
this.sync();
|
this.sync();
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
|
|
||||||
@@ -340,7 +338,9 @@ angular.module('app.frontend')
|
|||||||
this.unshareItem = function(item, callback) {
|
this.unshareItem = function(item, callback) {
|
||||||
item.presentation_name = null;
|
item.presentation_name = null;
|
||||||
var needsUpdate = [item].concat(item.referencesAffectedBySharingChange() || []);
|
var needsUpdate = [item].concat(item.referencesAffectedBySharingChange() || []);
|
||||||
modelManager.addDirtyItems(needsUpdate);
|
needsUpdate.forEach(function(needingUpdate){
|
||||||
|
needingUpdate.dirty = true;
|
||||||
|
})
|
||||||
this.sync(null);
|
this.sync(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,7 +351,9 @@ angular.module('app.frontend')
|
|||||||
this.importJSONData = function(jsonString, callback) {
|
this.importJSONData = function(jsonString, callback) {
|
||||||
var data = JSON.parse(jsonString);
|
var data = JSON.parse(jsonString);
|
||||||
modelManager.mapResponseItemsToLocalModels(data.items);
|
modelManager.mapResponseItemsToLocalModels(data.items);
|
||||||
modelManager.addDirtyItems(modelManager.items);
|
modelManager.items.forEach(function(item){
|
||||||
|
item.dirty = true;
|
||||||
|
})
|
||||||
this.syncWithOptions(callback, {additionalFields: ["created_at", "updated_at"]});
|
this.syncWithOptions(callback, {additionalFields: ["created_at", "updated_at"]});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,7 +401,7 @@ angular.module('app.frontend')
|
|||||||
request.items.forEach(function(item){
|
request.items.forEach(function(item){
|
||||||
if(item.tag_id) {
|
if(item.tag_id) {
|
||||||
var tag = tags.filter(function(tag){return tag.uuid == item.tag_id})[0];
|
var tag = tags.filter(function(tag){return tag.uuid == item.tag_id})[0];
|
||||||
item.tag_name = tag.content.title;
|
item.tag_name = tag.title;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
request.post().then(function(response){
|
request.post().then(function(response){
|
||||||
@@ -417,11 +419,13 @@ angular.module('app.frontend')
|
|||||||
return JSON.parse(JSON.stringify(object));
|
return JSON.parse(JSON.stringify(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.writeItemsToLocalStorage = function() {
|
this.writeItemsToLocalStorage = function(callback) {
|
||||||
var items = _.map(modelManager.items, function(item){
|
var items = _.map(modelManager.items, function(item){
|
||||||
return this.paramsForItem(item, false, ["created_at", "updated_at"], true)
|
return this.paramsForItem(item, false, ["created_at", "updated_at"], false)
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
console.log("writing items to local", items);
|
||||||
this.writeToLocalStorage('items', items);
|
this.writeToLocalStorage('items', items);
|
||||||
|
callback(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.writeToLocalStorage = function(key, value) {
|
this.writeToLocalStorage = function(key, value) {
|
||||||
@@ -431,7 +435,7 @@ angular.module('app.frontend')
|
|||||||
this.loadLocalItemsAndUser = function() {
|
this.loadLocalItemsAndUser = function() {
|
||||||
var user = {};
|
var user = {};
|
||||||
var items = JSON.parse(localStorage.getItem('items')) || [];
|
var items = JSON.parse(localStorage.getItem('items')) || [];
|
||||||
items = modelManager.mapResponseItemsToLocalModels(items);
|
items = this.handleItemsResponse(items);
|
||||||
Item.sortItemsByDate(items);
|
Item.sortItemsByDate(items);
|
||||||
user.items = items;
|
user.items = items;
|
||||||
user.shouldMerge = true;
|
user.shouldMerge = true;
|
||||||
@@ -490,7 +494,7 @@ angular.module('app.frontend')
|
|||||||
|
|
||||||
var ek = Neeto.crypto.firstHalfOfKey(item_key);
|
var ek = Neeto.crypto.firstHalfOfKey(item_key);
|
||||||
var ak = Neeto.crypto.secondHalfOfKey(item_key);
|
var ak = Neeto.crypto.secondHalfOfKey(item_key);
|
||||||
var encryptedContent = "001" + Neeto.crypto.encryptText(JSON.stringify(item.content), ek);
|
var encryptedContent = "001" + Neeto.crypto.encryptText(JSON.stringify(item.createContentJSONFromProperties()), ek);
|
||||||
var authHash = Neeto.crypto.hmac256(encryptedContent, ak);
|
var authHash = Neeto.crypto.hmac256(encryptedContent, ak);
|
||||||
|
|
||||||
item.content = encryptedContent;
|
item.content = encryptedContent;
|
||||||
|
|||||||
@@ -1,112 +0,0 @@
|
|||||||
class ItemManager {
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this._items = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
get items() {
|
|
||||||
return this._items;
|
|
||||||
}
|
|
||||||
|
|
||||||
findItem(itemId) {
|
|
||||||
return _.find(this.items, {uuid: itemId});
|
|
||||||
}
|
|
||||||
|
|
||||||
addItems(items) {
|
|
||||||
this._items = _.uniq(this.items.concat(items));
|
|
||||||
}
|
|
||||||
|
|
||||||
mapResponseItemsToLocalModels(items) {
|
|
||||||
return this.mapResponseItemsToLocalModelsOmittingFields(items, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
mapResponseItemsToLocalModelsOmittingFields(items, omitFields) {
|
|
||||||
var models = []
|
|
||||||
for (var json_obj of items) {
|
|
||||||
json_obj = _.omit(json_obj, omitFields || [])
|
|
||||||
var item = this.findItem(json_obj["uuid"]);
|
|
||||||
if(json_obj["deleted"] == true) {
|
|
||||||
if(item) {
|
|
||||||
this.deleteItem(item)
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(item) {
|
|
||||||
_.merge(item, json_obj);
|
|
||||||
} else {
|
|
||||||
item = this.createItem(json_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
models.push(item)
|
|
||||||
}
|
|
||||||
this.addItems(models)
|
|
||||||
this.resolveReferences()
|
|
||||||
return models;
|
|
||||||
}
|
|
||||||
|
|
||||||
createItem(json_obj) {
|
|
||||||
if(json_obj.content_type == "Note") {
|
|
||||||
return new Note(json_obj);
|
|
||||||
} else if(json_obj.content_type == "Tag") {
|
|
||||||
return new Tag(json_obj);
|
|
||||||
} else {
|
|
||||||
return new Item(json_obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resolveReferences() {
|
|
||||||
this.items.forEach(function(item){
|
|
||||||
// build out references, safely handle broken references
|
|
||||||
item.content.references = _.reduce(item.content.references, function(accumulator, reference){
|
|
||||||
var item = this.findItem(reference.uuid);
|
|
||||||
if(item) {
|
|
||||||
accumulator.push(item);
|
|
||||||
}
|
|
||||||
return accumulator;
|
|
||||||
}.bind(this), []);
|
|
||||||
}.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
itemsForContentType(contentType) {
|
|
||||||
return this.items.filter(function(item){
|
|
||||||
return item.content_type == contentType;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addItem(item) {
|
|
||||||
if(!this.findItem(item.uuid)) {
|
|
||||||
this.items.push(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns dirty item references that need saving
|
|
||||||
deleteItem(item) {
|
|
||||||
var dirty = [];
|
|
||||||
_.remove(this.items, item);
|
|
||||||
var length = item.content.references.length;
|
|
||||||
// note that references are deleted in this for loop, so you have to be careful how you iterate
|
|
||||||
for(var i = 0; i < length; i++) {
|
|
||||||
var referencedItem = item.content.references[0];
|
|
||||||
// console.log("removing references between items", referencedItem, item);
|
|
||||||
var _dirty = this.removeReferencesBetweenItems(referencedItem, item);
|
|
||||||
dirty = dirty.concat(_dirty);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
removeReferencesBetweenItems(itemOne, itemTwo) {
|
|
||||||
itemOne.removeReference(itemTwo);
|
|
||||||
itemTwo.removeReference(itemOne);
|
|
||||||
return [itemOne, itemTwo];
|
|
||||||
}
|
|
||||||
|
|
||||||
createReferencesBetweenItems(itemOne, itemTwo) {
|
|
||||||
itemOne.addReference(itemTwo);
|
|
||||||
itemTwo.addReference(itemOne);
|
|
||||||
return [itemOne, itemTwo];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
angular.module('app.frontend').service('itemManager', ItemManager);
|
|
||||||
|
|||||||
@@ -1,25 +1,107 @@
|
|||||||
class ModelManager extends ItemManager {
|
class ModelManager {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
|
||||||
this.notes = [];
|
this.notes = [];
|
||||||
this.tags = [];
|
this.tags = [];
|
||||||
this.dirtyItems = [];
|
|
||||||
this.changeObservers = [];
|
this.changeObservers = [];
|
||||||
|
this.items = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
findItem(itemId) {
|
||||||
|
return _.find(this.items, {uuid: itemId});
|
||||||
|
}
|
||||||
|
|
||||||
|
mapResponseItemsToLocalModels(items) {
|
||||||
|
return this.mapResponseItemsToLocalModelsOmittingFields(items, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
mapResponseItemsToLocalModelsOmittingFields(items, omitFields) {
|
||||||
|
var models = []
|
||||||
|
for (var json_obj of items) {
|
||||||
|
json_obj = _.omit(json_obj, omitFields || [])
|
||||||
|
var item = this.findItem(json_obj["uuid"]);
|
||||||
|
if(json_obj["deleted"] == true) {
|
||||||
|
if(item) {
|
||||||
|
this.removeItemLocally(item)
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_.omit(json_obj, omitFields);
|
||||||
|
|
||||||
|
if(!item) {
|
||||||
|
item = this.createItem(json_obj);
|
||||||
|
} else {
|
||||||
|
item.updateFromJSON(json_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
models.push(item)
|
||||||
|
}
|
||||||
|
this.addItems(models)
|
||||||
|
this.resolveReferences()
|
||||||
|
return models;
|
||||||
|
}
|
||||||
|
|
||||||
|
createItem(json_obj) {
|
||||||
|
if(json_obj.content_type == "Note") {
|
||||||
|
return new Note(json_obj);
|
||||||
|
} else if(json_obj.content_type == "Tag") {
|
||||||
|
return new Tag(json_obj);
|
||||||
|
} else {
|
||||||
|
return new Item(json_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addItems(items) {
|
||||||
|
this.items = _.uniq(this.items.concat(items));
|
||||||
|
|
||||||
|
items.forEach(function(item){
|
||||||
|
if(item.content_type == "Tag") {
|
||||||
|
if(!_.find(this.tags, {uuid: item.uuid})) {
|
||||||
|
this.tags.unshift(item);
|
||||||
|
}
|
||||||
|
} else if(item.content_type == "Note") {
|
||||||
|
if(!_.find(this.notes, {uuid: item.uuid})) {
|
||||||
|
this.notes.unshift(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.bind(this))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
addItem(item) {
|
||||||
|
this.addItems([item])
|
||||||
|
}
|
||||||
|
|
||||||
|
itemsForContentType(contentType) {
|
||||||
|
return this.items.filter(function(item){
|
||||||
|
return item.content_type == contentType;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveReferences() {
|
resolveReferences() {
|
||||||
super.resolveReferences()
|
for(var item of this.items) {
|
||||||
|
var contentObject = item.contentObject;
|
||||||
|
if(!contentObject.references) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var reference of contentObject.references) {
|
||||||
|
var referencedItem = this.findItem(reference.uuid);
|
||||||
|
if(referencedItem) {
|
||||||
|
item.addItemAsRelationship(referencedItem);
|
||||||
|
} else {
|
||||||
|
console.log("Unable to find item:", reference.uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.notes.push.apply(this.notes, _.difference(this.itemsForContentType("Note"), this.notes));
|
this.notes.push.apply(this.notes, _.difference(this.itemsForContentType("Note"), this.notes));
|
||||||
Item.sortItemsByDate(this.notes);
|
Item.sortItemsByDate(this.notes);
|
||||||
this.notes.forEach(function(note){
|
|
||||||
note.updateReferencesLocalMapping();
|
|
||||||
})
|
|
||||||
|
|
||||||
this.tags.push.apply(this.tags, _.difference(this.itemsForContentType("Tag"), this.tags));
|
this.tags.push.apply(this.tags, _.difference(this.itemsForContentType("Tag"), this.tags));
|
||||||
this.tags.forEach(function(tag){
|
this.tags.forEach(function(tag){
|
||||||
tag.updateReferencesLocalMapping();
|
Item.sortItemsByDate(tag.notes);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,86 +113,65 @@ class ModelManager extends ItemManager {
|
|||||||
_.remove(this.changeObservers, _.find(this.changeObservers, {id: id}));
|
_.remove(this.changeObservers, _.find(this.changeObservers, {id: id}));
|
||||||
}
|
}
|
||||||
|
|
||||||
addDirtyItems(items) {
|
|
||||||
if(!(items instanceof Array)) {
|
|
||||||
items = [items];
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dirtyItems = this.dirtyItems.concat(items);
|
|
||||||
this.dirtyItems = _.uniq(this.dirtyItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
get filteredNotes() {
|
get filteredNotes() {
|
||||||
return Note.filterDummyNotes(this.notes);
|
return Note.filterDummyNotes(this.notes);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearDirtyItems() {
|
notifyObserversOfSyncCompletion() {
|
||||||
console.log("Clearing dirty items", this.dirtyItems);
|
|
||||||
for(var observer of this.changeObservers) {
|
for(var observer of this.changeObservers) {
|
||||||
var changedItems = this.dirtyItems.filter(function(item){return item.content_type == observer.type});
|
var changedItems = this.dirtyItems.filter(function(item){return item.content_type == observer.type});
|
||||||
console.log("observer:", observer, "items", changedItems);
|
console.log("observer:", observer, "items", changedItems);
|
||||||
observer.callback(changedItems);
|
observer.callback(changedItems);
|
||||||
}
|
}
|
||||||
this.dirtyItems = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addNote(note) {
|
getDirtyItems() {
|
||||||
if(!_.find(this.notes, {uuid: note.uuid})) {
|
return this.items.filter(function(item){return item.dirty == true && !item.dummy})
|
||||||
this.notes.unshift(note);
|
}
|
||||||
this.addItem(note);
|
|
||||||
|
clearDirtyItems() {
|
||||||
|
this.notifyObserversOfSyncCompletion();
|
||||||
|
|
||||||
|
this.getDirtyItems().forEach(function(item){
|
||||||
|
item.dirty = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
setItemToBeDeleted(item) {
|
||||||
|
item.deleted = true;
|
||||||
|
item.dirty = true;
|
||||||
|
item.removeFromRelationships();
|
||||||
|
}
|
||||||
|
|
||||||
|
removeItemLocally(item) {
|
||||||
|
_.pull(this.items, item);
|
||||||
|
|
||||||
|
if(item.content_type == "Tag") {
|
||||||
|
_.pull(this.tags, item);
|
||||||
|
} else if(item.content_type == "Note") {
|
||||||
|
_.pull(this.notes, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addTag(tag) {
|
/*
|
||||||
this.tags.unshift(tag);
|
Relationships
|
||||||
this.addItem(tag);
|
*/
|
||||||
|
|
||||||
|
createRelationshipBetweenItems(itemOne, itemTwo) {
|
||||||
|
itemOne.addItemAsRelationship(itemTwo);
|
||||||
|
itemTwo.addItemAsRelationship(itemOne);
|
||||||
|
|
||||||
|
itemOne.dirty = true;
|
||||||
|
itemTwo.dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
addTagToNote(tag, note) {
|
removeRelationshipBetweenItems(itemOne, itemTwo) {
|
||||||
var dirty = this.createReferencesBetweenItems(tag, note);
|
itemOne.removeItemAsRelationship(itemTwo);
|
||||||
this.refreshRelationshipsForTag(tag);
|
itemTwo.removeItemAsRelationship(itemOne);
|
||||||
this.refreshRelationshipsForNote(note);
|
|
||||||
this.addDirtyItems(dirty);
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshRelationshipsForTag(tag) {
|
itemOne.dirty = true;
|
||||||
tag.notes = tag.referencesMatchingContentType("Note");
|
itemTwo.dirty = true;
|
||||||
Item.sortItemsByDate(tag.notes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshRelationshipsForNote(note) {
|
|
||||||
note.tags = note.referencesMatchingContentType("Tag");
|
|
||||||
}
|
|
||||||
|
|
||||||
removeTagFromNote(tag, note) {
|
|
||||||
var dirty = this.removeReferencesBetweenItems(tag, note);
|
|
||||||
this.addDirtyItems(dirty);
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteItem(item) {
|
|
||||||
var dirty = super.deleteItem(item);
|
|
||||||
if(item.content_type == "Note") {
|
|
||||||
_.remove(this.notes, item);
|
|
||||||
} else if(item.content_type == "Tag") {
|
|
||||||
_.remove(this.tags, item);
|
|
||||||
}
|
|
||||||
return dirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteNote(note) {
|
|
||||||
var dirty = this.deleteItem(note);
|
|
||||||
_.remove(this.notes, note);
|
|
||||||
if(!note.dummy) {
|
|
||||||
this.addDirtyItems(dirty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteTag(tag) {
|
|
||||||
var dirty = this.deleteItem(tag);
|
|
||||||
_.remove(this.tags, tag);
|
|
||||||
this.addDirtyItems(dirty);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
angular.module('app.frontend').service('modelManager', ModelManager);
|
angular.module('app.frontend').service('modelManager', ModelManager);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
.content
|
.content
|
||||||
.section-title-bar.editor-heading{"ng-class" => "{'shared' : ctrl.note.isPublic() }"}
|
.section-title-bar.editor-heading{"ng-class" => "{'shared' : ctrl.note.isPublic() }"}
|
||||||
.title
|
.title
|
||||||
%input.input#note-title-editor{"ng-model" => "ctrl.note.content.title", "ng-keyup" => "$event.keyCode == 13 && ctrl.saveTitle($event)",
|
%input.input#note-title-editor{"ng-model" => "ctrl.note.title", "ng-keyup" => "$event.keyCode == 13 && ctrl.saveTitle($event)",
|
||||||
"ng-disabled" => "ctrl.note.locked", "ng-change" => "ctrl.nameChanged()", "ng-focus" => "ctrl.onNameFocus()",
|
"ng-disabled" => "ctrl.note.locked", "ng-change" => "ctrl.nameChanged()", "ng-focus" => "ctrl.onNameFocus()",
|
||||||
"select-on-click" => "true"}
|
"select-on-click" => "true"}
|
||||||
.save-status {{ctrl.noteStatus}}
|
.save-status {{ctrl.noteStatus}}
|
||||||
@@ -51,8 +51,6 @@
|
|||||||
.sampler-container{"ng-if" => "ctrl.showSampler", "ng-click" => "ctrl.focusEditor()"}
|
.sampler-container{"ng-if" => "ctrl.showSampler", "ng-click" => "ctrl.focusEditor()"}
|
||||||
%strong.name-sampler.sampler{"typewrite" => "true", "text" => "ctrl.demoNoteNames", "type-delay" => "30", "initial-delay" => "1.5s",
|
%strong.name-sampler.sampler{"typewrite" => "true", "text" => "ctrl.demoNoteNames", "type-delay" => "30", "initial-delay" => "1.5s",
|
||||||
"iteration-callback" => "ctrl.callback", "prebegin-fn" => "ctrl.prebeginFn", "iteration-delay" => "2000", "cursor" => ""}
|
"iteration-callback" => "ctrl.callback", "prebegin-fn" => "ctrl.prebeginFn", "iteration-delay" => "2000", "cursor" => ""}
|
||||||
%code{"ng-if" => "ctrl.currentDemoContent.text"}
|
%textarea.editable#note-text-editor{"ng-disabled" => "ctrl.note.locked", "ng-show" => "ctrl.editorMode == 'edit'", "ng-model" => "ctrl.note.text",
|
||||||
.content-sampler.sampler{"typewrite" => "true", "text" => "ctrl.currentDemoContent.text", "type-delay" => "10", "iteration-callback" => "ctrl.contentCallback"}
|
|
||||||
%textarea.editable#note-text-editor{"ng-disabled" => "ctrl.note.locked", "ng-show" => "ctrl.editorMode == 'edit'", "ng-model" => "ctrl.note.content.text",
|
|
||||||
"ng-change" => "ctrl.contentChanged()", "ng-click" => "ctrl.clickedTextArea()", "ng-focus" => "ctrl.onContentFocus()"}
|
"ng-change" => "ctrl.contentChanged()", "ng-click" => "ctrl.clickedTextArea()", "ng-focus" => "ctrl.onContentFocus()"}
|
||||||
.preview{"ng-if" => "ctrl.editorMode == 'preview'", "ng-bind-html" => "ctrl.renderedContent()", "ng-dblclick" => "ctrl.onPreviewDoubleClick()"}
|
.preview{"ng-if" => "ctrl.editorMode == 'preview'", "ng-bind-html" => "ctrl.renderedContent()", "ng-dblclick" => "ctrl.onPreviewDoubleClick()"}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.section.notes
|
.section.notes
|
||||||
.content
|
.content
|
||||||
.section-title-bar.notes-title-bar
|
.section-title-bar.notes-title-bar
|
||||||
.title {{ctrl.tag.content.title}} notes
|
.title {{ctrl.tag.title}} notes
|
||||||
.add-button{"ng-click" => "ctrl.createNewNote()"} +
|
.add-button{"ng-click" => "ctrl.createNewNote()"} +
|
||||||
%br
|
%br
|
||||||
.filter-section
|
.filter-section
|
||||||
@@ -34,5 +34,5 @@
|
|||||||
"ng-click" => "ctrl.selectNote(note)", "ng-class" => "{'selected' : ctrl.selectedNote == note}",
|
"ng-click" => "ctrl.selectNote(note)", "ng-class" => "{'selected' : ctrl.selectedNote == note}",
|
||||||
"ng-attr-draggable" => "{{note.dummy ? undefined : 'true'}}", "note" => "note"}
|
"ng-attr-draggable" => "{{note.dummy ? undefined : 'true'}}", "note" => "note"}
|
||||||
.name
|
.name
|
||||||
{{note.content.title}}
|
{{note.title}}
|
||||||
.date {{(note.created_at | appDateTime) || 'Now'}}
|
.date {{(note.created_at | appDateTime) || 'Now'}}
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
{{ctrl.test}}
|
{{ctrl.test}}
|
||||||
.tag{"ng-if" => "ctrl.allTag", "ng-click" => "ctrl.selectTag(ctrl.allTag)", "ng-class" => "{'selected' : ctrl.selectedTag == ctrl.allTag}",
|
.tag{"ng-if" => "ctrl.allTag", "ng-click" => "ctrl.selectTag(ctrl.allTag)", "ng-class" => "{'selected' : ctrl.selectedTag == ctrl.allTag}",
|
||||||
"droppable" => true, "drop" => "ctrl.handleDrop", "tag" => "ctrl.allTag"}
|
"droppable" => true, "drop" => "ctrl.handleDrop", "tag" => "ctrl.allTag"}
|
||||||
%input.title{"ng-disabled" => "true", "ng-model" => "ctrl.allTag.content.title"}
|
%input.title{"ng-disabled" => "true", "ng-model" => "ctrl.allTag.title"}
|
||||||
.count {{ctrl.noteCount(ctrl.allTag)}}
|
.count {{ctrl.noteCount(ctrl.allTag)}}
|
||||||
|
|
||||||
.tag{"ng-repeat" => "tag in ctrl.tags", "ng-click" => "ctrl.selectTag(tag)", "ng-class" => "{'selected' : ctrl.selectedTag == tag}",
|
.tag{"ng-repeat" => "tag in ctrl.tags", "ng-click" => "ctrl.selectTag(tag)", "ng-class" => "{'selected' : ctrl.selectedTag == tag}",
|
||||||
"droppable" => true, "drop" => "ctrl.handleDrop", "tag" => "tag"}
|
"droppable" => true, "drop" => "ctrl.handleDrop", "tag" => "tag"}
|
||||||
.icon.icon-rss{"ng-if" => "tag.isPublic()"}
|
.icon.icon-rss{"ng-if" => "tag.isPublic()"}
|
||||||
%input.title{"ng-disabled" => "tag != ctrl.selectedTag", "ng-model" => "tag.content.title",
|
%input.title{"ng-disabled" => "tag != ctrl.selectedTag", "ng-model" => "tag.title",
|
||||||
"ng-keyup" => "$event.keyCode == 13 && ctrl.saveTag($event, tag)", "mb-autofocus" => "true", "should-focus" => "ctrl.newTag",
|
"ng-keyup" => "$event.keyCode == 13 && ctrl.saveTag($event, tag)", "mb-autofocus" => "true", "should-focus" => "ctrl.newTag",
|
||||||
"ng-change" => "ctrl.tagTitleDidChange(tag)", "ng-focus" => "ctrl.onTagTitleFocus(tag)"}
|
"ng-change" => "ctrl.tagTitleDidChange(tag)", "ng-focus" => "ctrl.onTagTitleFocus(tag)"}
|
||||||
.count {{ctrl.noteCount(tag)}}
|
.count {{ctrl.noteCount(tag)}}
|
||||||
|
|||||||
795
vendor/assets/javascripts/transpiled.js
vendored
795
vendor/assets/javascripts/transpiled.js
vendored
File diff suppressed because it is too large
Load Diff
2
vendor/assets/javascripts/transpiled.js.map
vendored
2
vendor/assets/javascripts/transpiled.js.map
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user