extension sync
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
461
vendor/assets/javascripts/transpiled.js
vendored
461
vendor/assets/javascripts/transpiled.js
vendored
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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