extension sync

This commit is contained in:
Mo Bitar
2017-01-05 15:42:35 -06:00
parent 117d6fca4e
commit 54ac4ffd15
10 changed files with 542 additions and 174 deletions

View File

@@ -53,6 +53,12 @@ angular.module('app.frontend')
})
}
this.reloadExtensionsPressed = function() {
if(confirm("For your security, reloading extensions will disable any currently enabled repeat actions.")) {
extensionManager.refreshExtensionsFromServer();
}
}
this.changeServer = function() {
apiController.setServer(this.serverData.url, true);
}

View File

@@ -1,14 +1,3 @@
class Extension extends Item {
constructor(json) {
super(json);
_.merge(this, json);
this.actions = this.actions.map(function(action){
return new Action(action);
})
}
}
class Action {
constructor(json) {
_.merge(this, json);
@@ -22,3 +11,44 @@ class Action {
}
}
}
class Extension extends Item {
constructor(json) {
super(json);
_.merge(this, json);
this.content_type = "Extension";
}
mapContentToLocalProperties(contentObject) {
super.mapContentToLocalProperties(contentObject)
this.name = contentObject.name;
this.url = contentObject.url;
this.actions = contentObject.actions.map(function(action){
return new Action(action);
})
}
updateFromExternalResponseItem(externalResponseItem) {
_.merge(this, externalResponseItem);
this.actions = externalResponseItem.actions.map(function(action){
return new Action(action);
})
}
referenceParams() {
return null;
}
structureParams() {
var params = {
name: this.name,
url: this.url,
actions: this.actions
};
_.merge(params, super.structureParams());
return params;
}
}

View File

@@ -234,7 +234,7 @@ angular.module('app.frontend')
return this.createRequestParamsForItem(item, options.additionalFields);
}.bind(this));
console.log("syncing items", request.items);
// console.log("syncing items", request.items);
if(this.syncToken) {
request.sync_token = this.syncToken;

View File

@@ -1,28 +1,78 @@
class ExtensionManager {
constructor(Restangular, modelManager) {
constructor(Restangular, modelManager, apiController) {
this.Restangular = Restangular;
this.modelManager = modelManager;
this.extensions = [];
this.enabledRepeatActions = [];
this.enabledRepeatActionUrls = localStorage.getItem("enabled_ext_urls") || [];
this.apiController = apiController;
this.enabledRepeatActionUrls = JSON.parse(localStorage.getItem("enabledRepeatActionUrls")) || [];
modelManager.addItemSyncObserver("extensionManager", "Extension", function(items){
for (var ext of items) {
for (var action of ext.actions) {
if(this.enabledRepeatActionUrls.includes(action.url)) {
this.enableRepeatAction(action, ext);
}
}
}
}.bind(this))
}
get extensions() {
return this.modelManager.extensions;
}
actionWithURL(url) {
for (var extension of this.extensions) {
return _.find(extension.actions, {url: url})
}
}
addExtension(url) {
this.retrieveExtensionFromServer(url, null);
}
retrieveExtensionFromServer(url, callback) {
console.log("Registering URL", url);
this.Restangular.oneUrl(url, url).get().then(function(response){
console.log("get response", response.plain());
var extension = new Extension(response.plain());
this.registerExtension(extension);
var ext = this.handleExtensionLoadExternalResponseItem(url, response.plain());
if(callback) {
callback(ext);
}
}.bind(this))
.catch(function(response){
console.log("Error registering extension", response);
})
}
registerExtension(extension) {
this.extensions.push(extension);
console.log("registered extensions", this.extensions);
handleExtensionLoadExternalResponseItem(url, externalResponseItem) {
var extension = _.find(this.extensions, {url: url});
if(extension) {
extension.updateFromExternalResponseItem(externalResponseItem);
console.log("updated existing ext", extension);
} else {
console.log("creating new ext", externalResponseItem);
extension = new Extension(externalResponseItem);
extension.url = url;
extension.dirty = true;
this.modelManager.addItem(extension);
this.apiController.sync(null);
}
return extension;
}
refreshExtensionsFromServer() {
for (var url of this.enabledRepeatActionUrls) {
var action = this.actionWithURL(url);
this.disableRepeatAction(action);
}
for(var ext of this.extensions) {
this.retrieveExtensionFromServer(ext.url, function(extension){
extension.dirty = true;
});
}
}
executeAction(action, extension, callback) {
@@ -43,46 +93,71 @@ class ExtensionManager {
disableRepeatAction(action, extension) {
console.log("Disabling action", action);
_.pull(this.enabledRepeatActionUrls, action.url);
_.pull(this.enabledRepeatActions, action);
this.modelManager.removeItemObserver(action.url);
this.modelManager.removeItemSyncObserver(action.url);
console.assert(this.isRepeatActionEnabled(action) == false);
}
enableRepeatAction(action, extension) {
console.log("Enabling repeat action", action);
this.enabledRepeatActionUrls.push(action.url);
this.enabledRepeatActions.push(action);
if(!_.find(this.enabledRepeatActionUrls, action.url)) {
this.enabledRepeatActionUrls.push(action.url);
localStorage.setItem("enabledRepeatActionUrls", JSON.stringify(this.enabledRepeatActionUrls));
}
if(action.repeatType == "watch") {
for(var structure of action.structures) {
this.modelManager.addItemObserver(action.url, structure.type, function(changedItems){
this.modelManager.addItemSyncObserver(action.url, structure.type, function(changedItems){
this.triggerWatchAction(action, changedItems);
}.bind(this))
}
}
}
queueAction(action, delay, changedItems) {
this.actionQueue = this.actionQueue || [];
if(_.find(this.actionQueue, action)) {
// console.log("Action already queued, skipping.")
return;
}
// console.log("Adding action to queue", action);
this.actionQueue.push(action);
setTimeout(function () {
console.log("Performing queued action", action);
this.triggerWatchAction(action, changedItems);
_.pull(this.actionQueue, action);
}.bind(this), delay * 1000);
}
triggerWatchAction(action, changedItems) {
console.log("Watch action triggered", action, changedItems);
// console.log("Watch action triggered", action, changedItems);
if(action.repeatFrequency > 0) {
var lastExecuted = action.lastExecuted;
var diffInSeconds = (new Date() - lastExecuted)/1000;
console.log("last executed", action.lastExecuted, "diff", diffInSeconds, "repeatFreq", action.repeatFrequency);
if(diffInSeconds < action.repeatFrequency) {
console.log("too frequent, returning");
var delay = action.repeatFrequency - diffInSeconds;
console.log("delaying action by", delay);
this.queueAction(action, delay, changedItems);
return;
}
}
console.log("Performing action immediately", action);
action.lastExecuted = new Date();
// console.log("setting last exectured", action.lastExecuted)
if(action.repeatVerb == "post") {
var request = this.Restangular.oneUrl(action.url, action.url);
request.items = changedItems.map(function(item){
var params = {uuid: item.uuid, content_type: item.content_type, content: item.content};
var params = {uuid: item.uuid, content_type: item.content_type, content: item.createContentJSONFromProperties()};
return params;
})
request.post().then(function(response){
console.log("watch action response", response);
action.lastExecuted = new Date();
// console.log("watch action response", response);
})
}
}

View File

@@ -3,8 +3,9 @@ class ModelManager {
constructor() {
this.notes = [];
this.tags = [];
this.changeObservers = [];
this.itemSyncObservers = [];
this.items = [];
this.extensions = [];
}
findItem(itemId) {
@@ -44,6 +45,13 @@ class ModelManager {
models.push(item)
}
for(var observer of this.itemSyncObservers) {
var relevantItems = models.filter(function(item){return item.content_type == observer.type});
if(relevantItems.length > 0) {
observer.callback(relevantItems);
}
}
this.sortItems();
return models;
}
@@ -53,6 +61,8 @@ class ModelManager {
return new Note(json_obj);
} else if(json_obj.content_type == "Tag") {
return new Tag(json_obj);
} else if(json_obj.content_type == "Extension") {
return new Extension(json_obj);
} else {
return new Item(json_obj);
}
@@ -70,6 +80,10 @@ class ModelManager {
if(!_.find(this.notes, {uuid: item.uuid})) {
this.notes.unshift(item);
}
} else if(item.content_type == "Extension") {
if(!_.find(this.extensions, {uuid: item.uuid})) {
this.extensions.unshift(item);
}
}
}.bind(this))
}
@@ -85,7 +99,6 @@ class ModelManager {
}
resolveReferencesForItem(item) {
var contentObject = item.contentObject;
if(!contentObject.references) {
return;
@@ -100,7 +113,6 @@ class ModelManager {
console.log("Unable to find item:", reference.uuid);
}
}
}
sortItems() {
@@ -111,33 +123,23 @@ class ModelManager {
})
}
addItemObserver(id, type, callback) {
this.changeObservers.push({id: id, type: type, callback: callback});
addItemSyncObserver(id, type, callback) {
this.itemSyncObservers.push({id: id, type: type, callback: callback});
}
removeItemObserver(id) {
_.remove(this.changeObservers, _.find(this.changeObservers, {id: id}));
removeItemSyncObserver(id) {
_.remove(this.itemSyncObservers, _.find(this.itemSyncObservers, {id: id}));
}
get filteredNotes() {
return Note.filterDummyNotes(this.notes);
}
notifyObserversOfSyncCompletion() {
for(var observer of this.changeObservers) {
var changedItems = this.dirtyItems.filter(function(item){return item.content_type == observer.type});
console.log("observer:", observer, "items", changedItems);
observer.callback(changedItems);
}
}
getDirtyItems() {
return this.items.filter(function(item){return item.dirty == true && !item.dummy})
}
clearDirtyItems() {
this.notifyObserversOfSyncCompletion();
this.getDirtyItems().forEach(function(item){
item.dirty = false;
})
@@ -156,6 +158,8 @@ class ModelManager {
_.pull(this.tags, item);
} else if(item.content_type == "Note") {
_.pull(this.notes, item);
} else if(item.content_type == "Extension") {
_.pull(this.extensions, item);
}
}

View File

@@ -267,6 +267,14 @@ Extensions
.extensions-panel {
font-size: 14px;
.extension-link {
margin-top: 6px;
a {
font-weight: bold;
}
}
}
.extension-form {
@@ -282,6 +290,12 @@ Extensions
padding: 10px;
color: black;
a {
color: $blue-color !important;
font-size: 12px !important;
font-weight: bold !important;
}
> .name {
font-weight: bold;
font-size: 16px;
@@ -295,7 +309,7 @@ Extensions
> .actions {
margin-top: 15px;
font-size: 14px;
font-size: 12px;
.action {
margin-bottom: 10px;
@@ -305,9 +319,6 @@ Extensions
}
> .execute {
a {
color: $blue-color;
}
font-weight: bold;
margin-bottom: 3px;
font-size: 12px;
@@ -315,6 +326,7 @@ Extensions
> .execute-type {
font-size: 12px;
margin-bottom: 1px;
}
> .last-run {

View File

@@ -95,6 +95,17 @@
.actions
.action{"ng-repeat" => "action in extension.actions"}
.name {{action.label}}
.desc{"style" => "font-style: italic;"} {{action.desc}}
.execute-type{"ng-if" => "action.repeatable"}
Repeats at most once every {{action.repeatFrequency}} seconds
.last-run{"ng-if" => "action.lastExecuted"}
Last executed {{action.lastExecuted | appDate}}
.permissions
%a{"ng-click" => "action.showPermissions = !action.showPermissions"} {{action.showPermissions ? "Hide permissions" : "Show permissions"}}
.permission-model{"ng-if" => "action.showPermissions", "ng-repeat" => "structure in action.structures"}
%span{"style" => "font-weight: bold;"} {{structure.type}}s:
%span{"ng-repeat" => "field in structure.fields"}
{{field.name}} ({{field.modifies ? "readwrite" : "read"}})
.execute
%a{"ng-click" => "ctrl.selectedAction(action, extension)"}
%span{"ng-if" => "action.repeatable"}
@@ -102,18 +113,19 @@
%span{"ng-if" => "!ctrl.extensionManager.isRepeatActionEnabled(action)", "ng-click" => "ctrl.extensionManager.enableRepeatAction(action, extension)"} Enable
%span{"ng-if" => "!action.repeatable"}
Perform Action
.execute-type{"ng-if" => "action.repeatable"}
This is a repeat action.
.last-run{"ng-if" => "action.lastExecuted"}
Last executed {{action.lastExecuted | appDate}}
%a{"ng-click" => "ctrl.toggleExtensionForm()"} Add new extension
.extension-link
%a{"ng-click" => "ctrl.toggleExtensionForm()"} Add new extension
%form.extension-form{"ng-if" => "ctrl.showNewExtensionForm"}
.form-tag.has-feedback
%input.form-control{:autofocus => 'autofocus', :name => 'url', :placeholder => 'Extension URL', :required => true, :type => 'text', 'ng-model' => 'ctrl.newExtensionData.url'}
%button.btn.dark-button.btn-block{:type => 'submit', "data-style" => "expand-right", "data-size" => "s", "state" => "buttonState"}
%span.ladda-label{"ng-click" => "ctrl.submitNewExtensionForm()"} Add Extension
.extension-link
%a{"ng-click" => "ctrl.reloadExtensionsPressed()", "ng-if" => "ctrl.extensionManager.extensions.length > 0"} Reload all extensions
.item
%a{"href" => "https://standardnotes.org", "target" => "_blank"}
Help

View File

@@ -765,6 +765,12 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
});
};
this.reloadExtensionsPressed = function () {
if (confirm("For your security, reloading extensions will disable any currently enabled repeat actions.")) {
extensionManager.refreshExtensionsFromServer();
}
};
this.changeServer = function () {
apiController.setServer(this.serverData.url, true);
};
@@ -1432,25 +1438,6 @@ var Item = function () {
}();
;
var Extension = function (_Item) {
_inherits(Extension, _Item);
function Extension(json) {
_classCallCheck(this, Extension);
var _this3 = _possibleConstructorReturn(this, (Extension.__proto__ || Object.getPrototypeOf(Extension)).call(this, json));
_.merge(_this3, json);
_this3.actions = _this3.actions.map(function (action) {
return new Action(action);
});
return _this3;
}
return Extension;
}(Item);
var Action = function Action(json) {
_classCallCheck(this, Action);
@@ -1465,6 +1452,60 @@ var Action = function Action(json) {
}
};
var Extension = function (_Item) {
_inherits(Extension, _Item);
function Extension(json) {
_classCallCheck(this, Extension);
var _this3 = _possibleConstructorReturn(this, (Extension.__proto__ || Object.getPrototypeOf(Extension)).call(this, json));
_.merge(_this3, json);
_this3.content_type = "Extension";
return _this3;
}
_createClass(Extension, [{
key: 'mapContentToLocalProperties',
value: function mapContentToLocalProperties(contentObject) {
_get(Extension.prototype.__proto__ || Object.getPrototypeOf(Extension.prototype), 'mapContentToLocalProperties', this).call(this, contentObject);
this.name = contentObject.name;
this.url = contentObject.url;
this.actions = contentObject.actions.map(function (action) {
return new Action(action);
});
}
}, {
key: 'updateFromExternalResponseItem',
value: function updateFromExternalResponseItem(externalResponseItem) {
_.merge(this, externalResponseItem);
this.actions = externalResponseItem.actions.map(function (action) {
return new Action(action);
});
}
}, {
key: 'referenceParams',
value: function referenceParams() {
return null;
}
}, {
key: 'structureParams',
value: function structureParams() {
var params = {
name: this.name,
url: this.url,
actions: this.actions
};
_.merge(params, _get(Extension.prototype.__proto__ || Object.getPrototypeOf(Extension.prototype), 'structureParams', this).call(this));
return params;
}
}]);
return Extension;
}(Item);
;
var Note = function (_Item2) {
_inherits(Note, _Item2);
@@ -1932,7 +1973,7 @@ var User = function User(json_obj) {
return this.createRequestParamsForItem(item, options.additionalFields);
}.bind(this));
console.log("syncing items", request.items);
// console.log("syncing items", request.items);
if (this.syncToken) {
request.sync_token = this.syncToken;
@@ -2607,33 +2648,186 @@ angular.module('app.frontend').directive('typewrite', ['$timeout', function ($ti
}]);
;
var ExtensionManager = function () {
function ExtensionManager(Restangular, modelManager) {
function ExtensionManager(Restangular, modelManager, apiController) {
_classCallCheck(this, ExtensionManager);
this.Restangular = Restangular;
this.modelManager = modelManager;
this.extensions = [];
this.enabledRepeatActions = [];
this.enabledRepeatActionUrls = localStorage.getItem("enabled_ext_urls") || [];
this.apiController = apiController;
this.enabledRepeatActionUrls = JSON.parse(localStorage.getItem("enabledRepeatActionUrls")) || [];
modelManager.addItemSyncObserver("extensionManager", "Extension", function (items) {
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = items[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var ext = _step3.value;
var _iteratorNormalCompletion4 = true;
var _didIteratorError4 = false;
var _iteratorError4 = undefined;
try {
for (var _iterator4 = ext.actions[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
var action = _step4.value;
if (this.enabledRepeatActionUrls.includes(action.url)) {
this.enableRepeatAction(action, ext);
}
}
} catch (err) {
_didIteratorError4 = true;
_iteratorError4 = err;
} finally {
try {
if (!_iteratorNormalCompletion4 && _iterator4.return) {
_iterator4.return();
}
} finally {
if (_didIteratorError4) {
throw _iteratorError4;
}
}
}
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
}.bind(this));
}
_createClass(ExtensionManager, [{
key: 'actionWithURL',
value: function actionWithURL(url) {
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
var _iteratorError5 = undefined;
try {
for (var _iterator5 = this.extensions[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
var extension = _step5.value;
return _.find(extension.actions, { url: url });
}
} catch (err) {
_didIteratorError5 = true;
_iteratorError5 = err;
} finally {
try {
if (!_iteratorNormalCompletion5 && _iterator5.return) {
_iterator5.return();
}
} finally {
if (_didIteratorError5) {
throw _iteratorError5;
}
}
}
}
}, {
key: 'addExtension',
value: function addExtension(url) {
this.retrieveExtensionFromServer(url, null);
}
}, {
key: 'retrieveExtensionFromServer',
value: function retrieveExtensionFromServer(url, callback) {
console.log("Registering URL", url);
this.Restangular.oneUrl(url, url).get().then(function (response) {
console.log("get response", response.plain());
var extension = new Extension(response.plain());
this.registerExtension(extension);
var ext = this.handleExtensionLoadExternalResponseItem(url, response.plain());
if (callback) {
callback(ext);
}
}.bind(this)).catch(function (response) {
console.log("Error registering extension", response);
});
}
}, {
key: 'registerExtension',
value: function registerExtension(extension) {
this.extensions.push(extension);
console.log("registered extensions", this.extensions);
key: 'handleExtensionLoadExternalResponseItem',
value: function handleExtensionLoadExternalResponseItem(url, externalResponseItem) {
var extension = _.find(this.extensions, { url: url });
if (extension) {
extension.updateFromExternalResponseItem(externalResponseItem);
console.log("updated existing ext", extension);
} else {
console.log("creating new ext", externalResponseItem);
extension = new Extension(externalResponseItem);
extension.url = url;
extension.dirty = true;
this.modelManager.addItem(extension);
this.apiController.sync(null);
}
return extension;
}
}, {
key: 'refreshExtensionsFromServer',
value: function refreshExtensionsFromServer() {
var _iteratorNormalCompletion6 = true;
var _didIteratorError6 = false;
var _iteratorError6 = undefined;
try {
for (var _iterator6 = this.enabledRepeatActionUrls[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
var url = _step6.value;
var action = this.actionWithURL(url);
this.disableRepeatAction(action);
}
} catch (err) {
_didIteratorError6 = true;
_iteratorError6 = err;
} finally {
try {
if (!_iteratorNormalCompletion6 && _iterator6.return) {
_iterator6.return();
}
} finally {
if (_didIteratorError6) {
throw _iteratorError6;
}
}
}
var _iteratorNormalCompletion7 = true;
var _didIteratorError7 = false;
var _iteratorError7 = undefined;
try {
for (var _iterator7 = this.extensions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
var ext = _step7.value;
this.retrieveExtensionFromServer(ext.url, function (extension) {
extension.dirty = true;
});
}
} catch (err) {
_didIteratorError7 = true;
_iteratorError7 = err;
} finally {
try {
if (!_iteratorNormalCompletion7 && _iterator7.return) {
_iterator7.return();
}
} finally {
if (_didIteratorError7) {
throw _iteratorError7;
}
}
}
}
}, {
key: 'executeAction',
@@ -2657,8 +2851,7 @@ var ExtensionManager = function () {
value: function disableRepeatAction(action, extension) {
console.log("Disabling action", action);
_.pull(this.enabledRepeatActionUrls, action.url);
_.pull(this.enabledRepeatActions, action);
this.modelManager.removeItemObserver(action.url);
this.modelManager.removeItemSyncObserver(action.url);
console.assert(this.isRepeatActionEnabled(action) == false);
}
}, {
@@ -2666,63 +2859,95 @@ var ExtensionManager = function () {
value: function enableRepeatAction(action, extension) {
console.log("Enabling repeat action", action);
this.enabledRepeatActionUrls.push(action.url);
this.enabledRepeatActions.push(action);
if (!_.find(this.enabledRepeatActionUrls, action.url)) {
this.enabledRepeatActionUrls.push(action.url);
localStorage.setItem("enabledRepeatActionUrls", JSON.stringify(this.enabledRepeatActionUrls));
}
if (action.repeatType == "watch") {
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
var _iteratorNormalCompletion8 = true;
var _didIteratorError8 = false;
var _iteratorError8 = undefined;
try {
for (var _iterator3 = action.structures[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var structure = _step3.value;
for (var _iterator8 = action.structures[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
var structure = _step8.value;
this.modelManager.addItemObserver(action.url, structure.type, function (changedItems) {
this.modelManager.addItemSyncObserver(action.url, structure.type, function (changedItems) {
this.triggerWatchAction(action, changedItems);
}.bind(this));
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
_didIteratorError8 = true;
_iteratorError8 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
if (!_iteratorNormalCompletion8 && _iterator8.return) {
_iterator8.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
if (_didIteratorError8) {
throw _iteratorError8;
}
}
}
}
}
}, {
key: 'queueAction',
value: function queueAction(action, delay, changedItems) {
this.actionQueue = this.actionQueue || [];
if (_.find(this.actionQueue, action)) {
// console.log("Action already queued, skipping.")
return;
}
// console.log("Adding action to queue", action);
this.actionQueue.push(action);
setTimeout(function () {
console.log("Performing queued action", action);
this.triggerWatchAction(action, changedItems);
_.pull(this.actionQueue, action);
}.bind(this), delay * 1000);
}
}, {
key: 'triggerWatchAction',
value: function triggerWatchAction(action, changedItems) {
console.log("Watch action triggered", action, changedItems);
// console.log("Watch action triggered", action, changedItems);
if (action.repeatFrequency > 0) {
var lastExecuted = action.lastExecuted;
var diffInSeconds = (new Date() - lastExecuted) / 1000;
console.log("last executed", action.lastExecuted, "diff", diffInSeconds, "repeatFreq", action.repeatFrequency);
if (diffInSeconds < action.repeatFrequency) {
console.log("too frequent, returning");
var delay = action.repeatFrequency - diffInSeconds;
console.log("delaying action by", delay);
this.queueAction(action, delay, changedItems);
return;
}
}
console.log("Performing action immediately", action);
action.lastExecuted = new Date();
// console.log("setting last exectured", action.lastExecuted)
if (action.repeatVerb == "post") {
var request = this.Restangular.oneUrl(action.url, action.url);
request.items = changedItems.map(function (item) {
var params = { uuid: item.uuid, content_type: item.content_type, content: item.content };
var params = { uuid: item.uuid, content_type: item.content_type, content: item.createContentJSONFromProperties() };
return params;
});
request.post().then(function (response) {
console.log("watch action response", response);
action.lastExecuted = new Date();
// console.log("watch action response", response);
});
}
}
}, {
key: 'extensions',
get: function get() {
return this.modelManager.extensions;
}
}]);
return ExtensionManager;
@@ -2738,7 +2963,7 @@ angular.module('app.frontend').service('extensionManager', ExtensionManager);
return input ? $filter('date')(new Date(input), 'MM/dd/yyyy h:mm a') : '';
};
});
;;angular.module('app.frontend').service('markdownRenderer', function ($sce) {
;angular.module('app.frontend').service('markdownRenderer', function ($sce) {
marked.setOptions({
breaks: true,
@@ -2763,8 +2988,9 @@ var ModelManager = function () {
this.notes = [];
this.tags = [];
this.changeObservers = [];
this.itemSyncObservers = [];
this.items = [];
this.extensions = [];
}
_createClass(ModelManager, [{
@@ -2781,13 +3007,13 @@ var ModelManager = function () {
key: 'mapResponseItemsToLocalModelsOmittingFields',
value: function mapResponseItemsToLocalModelsOmittingFields(items, omitFields) {
var models = [];
var _iteratorNormalCompletion4 = true;
var _didIteratorError4 = false;
var _iteratorError4 = undefined;
var _iteratorNormalCompletion9 = true;
var _didIteratorError9 = false;
var _iteratorError9 = undefined;
try {
for (var _iterator4 = items[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
var json_obj = _step4.value;
for (var _iterator9 = items[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
var json_obj = _step9.value;
json_obj = _.omit(json_obj, omitFields || []);
var item = this.findItem(json_obj["uuid"]);
@@ -2815,16 +3041,46 @@ var ModelManager = function () {
models.push(item);
}
} catch (err) {
_didIteratorError4 = true;
_iteratorError4 = err;
_didIteratorError9 = true;
_iteratorError9 = err;
} finally {
try {
if (!_iteratorNormalCompletion4 && _iterator4.return) {
_iterator4.return();
if (!_iteratorNormalCompletion9 && _iterator9.return) {
_iterator9.return();
}
} finally {
if (_didIteratorError4) {
throw _iteratorError4;
if (_didIteratorError9) {
throw _iteratorError9;
}
}
}
var _iteratorNormalCompletion10 = true;
var _didIteratorError10 = false;
var _iteratorError10 = undefined;
try {
for (var _iterator10 = this.itemSyncObservers[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
var observer = _step10.value;
var relevantItems = models.filter(function (item) {
return item.content_type == observer.type;
});
if (relevantItems.length > 0) {
observer.callback(relevantItems);
}
}
} catch (err) {
_didIteratorError10 = true;
_iteratorError10 = err;
} finally {
try {
if (!_iteratorNormalCompletion10 && _iterator10.return) {
_iterator10.return();
}
} finally {
if (_didIteratorError10) {
throw _iteratorError10;
}
}
}
@@ -2839,6 +3095,8 @@ var ModelManager = function () {
return new Note(json_obj);
} else if (json_obj.content_type == "Tag") {
return new Tag(json_obj);
} else if (json_obj.content_type == "Extension") {
return new Extension(json_obj);
} else {
return new Item(json_obj);
}
@@ -2857,6 +3115,10 @@ var ModelManager = function () {
if (!_.find(this.notes, { uuid: item.uuid })) {
this.notes.unshift(item);
}
} else if (item.content_type == "Extension") {
if (!_.find(this.extensions, { uuid: item.uuid })) {
this.extensions.unshift(item);
}
}
}.bind(this));
}
@@ -2875,19 +3137,18 @@ var ModelManager = function () {
}, {
key: 'resolveReferencesForItem',
value: function resolveReferencesForItem(item) {
var contentObject = item.contentObject;
if (!contentObject.references) {
return;
}
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
var _iteratorError5 = undefined;
var _iteratorNormalCompletion11 = true;
var _didIteratorError11 = false;
var _iteratorError11 = undefined;
try {
for (var _iterator5 = contentObject.references[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
var reference = _step5.value;
for (var _iterator11 = contentObject.references[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
var reference = _step11.value;
var referencedItem = this.findItem(reference.uuid);
if (referencedItem) {
@@ -2898,16 +3159,16 @@ var ModelManager = function () {
}
}
} catch (err) {
_didIteratorError5 = true;
_iteratorError5 = err;
_didIteratorError11 = true;
_iteratorError11 = err;
} finally {
try {
if (!_iteratorNormalCompletion5 && _iterator5.return) {
_iterator5.return();
if (!_iteratorNormalCompletion11 && _iterator11.return) {
_iterator11.return();
}
} finally {
if (_didIteratorError5) {
throw _iteratorError5;
if (_didIteratorError11) {
throw _iteratorError11;
}
}
}
@@ -2922,46 +3183,14 @@ var ModelManager = function () {
});
}
}, {
key: 'addItemObserver',
value: function addItemObserver(id, type, callback) {
this.changeObservers.push({ id: id, type: type, callback: callback });
key: 'addItemSyncObserver',
value: function addItemSyncObserver(id, type, callback) {
this.itemSyncObservers.push({ id: id, type: type, callback: callback });
}
}, {
key: 'removeItemObserver',
value: function removeItemObserver(id) {
_.remove(this.changeObservers, _.find(this.changeObservers, { id: id }));
}
}, {
key: 'notifyObserversOfSyncCompletion',
value: function notifyObserversOfSyncCompletion() {
var _iteratorNormalCompletion6 = true;
var _didIteratorError6 = false;
var _iteratorError6 = undefined;
try {
for (var _iterator6 = this.changeObservers[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
var observer = _step6.value;
var changedItems = this.dirtyItems.filter(function (item) {
return item.content_type == observer.type;
});
console.log("observer:", observer, "items", changedItems);
observer.callback(changedItems);
}
} catch (err) {
_didIteratorError6 = true;
_iteratorError6 = err;
} finally {
try {
if (!_iteratorNormalCompletion6 && _iterator6.return) {
_iterator6.return();
}
} finally {
if (_didIteratorError6) {
throw _iteratorError6;
}
}
}
key: 'removeItemSyncObserver',
value: function removeItemSyncObserver(id) {
_.remove(this.itemSyncObservers, _.find(this.itemSyncObservers, { id: id }));
}
}, {
key: 'getDirtyItems',
@@ -2973,8 +3202,6 @@ var ModelManager = function () {
}, {
key: 'clearDirtyItems',
value: function clearDirtyItems() {
this.notifyObserversOfSyncCompletion();
this.getDirtyItems().forEach(function (item) {
item.dirty = false;
});
@@ -2995,6 +3222,8 @@ var ModelManager = function () {
_.pull(this.tags, item);
} else if (item.content_type == "Note") {
_.pull(this.notes, item);
} else if (item.content_type == "Extension") {
_.pull(this.extensions, item);
}
}

File diff suppressed because one or more lines are too long