diff options
Diffstat (limited to 'web/src/js/stores')
-rw-r--r-- | web/src/js/stores/base.js | 25 | ||||
-rw-r--r-- | web/src/js/stores/eventlogstore.js | 99 | ||||
-rw-r--r-- | web/src/js/stores/flowstore.js | 91 | ||||
-rw-r--r-- | web/src/js/stores/settingstore.js | 28 |
4 files changed, 243 insertions, 0 deletions
diff --git a/web/src/js/stores/base.js b/web/src/js/stores/base.js new file mode 100644 index 00000000..952fa847 --- /dev/null +++ b/web/src/js/stores/base.js @@ -0,0 +1,25 @@ +function EventEmitter() { + this.listeners = {}; +} +EventEmitter.prototype.emit = function (event) { + if (!(event in this.listeners)) { + return; + } + var args = Array.prototype.slice.call(arguments, 1); + this.listeners[event].forEach(function (listener) { + listener.apply(this, args); + }.bind(this)); +}; +EventEmitter.prototype.addListener = function (event, f) { + this.listeners[event] = this.listeners[event] || []; + this.listeners[event].push(f); +}; +EventEmitter.prototype.removeListener = function (event, f) { + if (!(event in this.listeners)) { + return false; + } + var index = this.listeners[event].indexOf(f); + if (index >= 0) { + this.listeners[event].splice(index, 1); + } +}; diff --git a/web/src/js/stores/eventlogstore.js b/web/src/js/stores/eventlogstore.js new file mode 100644 index 00000000..e356959a --- /dev/null +++ b/web/src/js/stores/eventlogstore.js @@ -0,0 +1,99 @@ +// +// We have an EventLogView and an EventLogStore: +// The basic architecture is that one can request views on the event log +// from the store, which returns a view object and then deals with getting the data required for the view. +// The view object is accessed by React components and distributes updates etc. +// +// See also: components/EventLog.react.js +function EventLogView(store, live) { + EventEmitter.call(this); + this._store = store; + this.live = live; + this.log = []; + + this.add = this.add.bind(this); + + if (live) { + this._store.addListener(ActionTypes.ADD_EVENT, this.add); + } +} +_.extend(EventLogView.prototype, EventEmitter.prototype, { + close: function () { + this._store.removeListener(ActionTypes.ADD_EVENT, this.add); + }, + getAll: function () { + return this.log; + }, + add: function (entry) { + this.log.push(entry); + if(this.log.length > 200){ + this.log.shift(); + } + this.emit("change"); + }, + add_bulk: function (messages) { + var log = messages; + var last_id = log[log.length - 1].id; + var to_add = _.filter(this.log, function (entry) { + return entry.id > last_id; + }); + this.log = log.concat(to_add); + this.emit("change"); + } +}); + + +function _EventLogStore() { + EventEmitter.call(this); +} +_.extend(_EventLogStore.prototype, EventEmitter.prototype, { + getView: function (since) { + var view = new EventLogView(this, !since); + return view; + /* + //TODO: Really do bulk retrieval of last messages. + window.setTimeout(function () { + view.add_bulk([ + { + id: 1, + message: "Hello World" + }, + { + id: 2, + message: "I was already transmitted as an event." + } + ]); + }, 100); + + var id = 2; + view.add({ + id: id++, + message: "I was already transmitted as an event." + }); + view.add({ + id: id++, + message: "I was only transmitted as an event before the bulk was added.." + }); + window.setInterval(function () { + view.add({ + id: id++, + message: "." + }); + }, 1000); + return view; + */ + }, + handle: function (action) { + switch (action.type) { + case ActionTypes.ADD_EVENT: + this.emit(ActionTypes.ADD_EVENT, action.data); + break; + default: + return; + } + } +}); + + +var EventLogStore = new _EventLogStore(); +AppDispatcher.register(EventLogStore.handle.bind(EventLogStore));
\ No newline at end of file diff --git a/web/src/js/stores/flowstore.js b/web/src/js/stores/flowstore.js new file mode 100644 index 00000000..7c0bddbd --- /dev/null +++ b/web/src/js/stores/flowstore.js @@ -0,0 +1,91 @@ +function FlowView(store, live) { + EventEmitter.call(this); + this._store = store; + this.live = live; + this.flows = []; + + this.add = this.add.bind(this); + this.update = this.update.bind(this); + + if (live) { + this._store.addListener(ActionTypes.ADD_FLOW, this.add); + this._store.addListener(ActionTypes.UPDATE_FLOW, this.update); + } +} + +_.extend(FlowView.prototype, EventEmitter.prototype, { + close: function () { + this._store.removeListener(ActionTypes.ADD_FLOW, this.add); + this._store.removeListener(ActionTypes.UPDATE_FLOW, this.update); + }, + getAll: function () { + return this.flows; + }, + add: function (flow) { + return this.update(flow); + }, + add_bulk: function (flows) { + //Treat all previously received updates as newer than the bulk update. + //If they weren't newer, we're about to receive an update for them very soon. + var updates = this.flows; + this.flows = flows; + updates.forEach(function(flow){ + this._update(flow); + }.bind(this)); + this.emit("change"); + }, + _update: function(flow){ + var idx = _.findIndex(this.flows, function(f){ + return flow.id === f.id; + }); + + if(idx < 0){ + this.flows.push(flow); + //if(this.flows.length > 100){ + // this.flows.shift(); + //} + } else { + this.flows[idx] = flow; + } + }, + update: function(flow){ + this._update(flow); + this.emit("change"); + }, +}); + + +function _FlowStore() { + EventEmitter.call(this); +} +_.extend(_FlowStore.prototype, EventEmitter.prototype, { + getView: function (since) { + var view = new FlowView(this, !since); + + $.getJSON("/static/flows.json", function(flows){ + flows = flows.concat(_.cloneDeep(flows)).concat(_.cloneDeep(flows)); + var id = 1; + flows.forEach(function(flow){ + flow.id = "uuid-" + id++; + }); + view.add_bulk(flows); + + }); + + return view; + }, + handle: function (action) { + switch (action.type) { + case ActionTypes.ADD_FLOW: + case ActionTypes.UPDATE_FLOW: + this.emit(action.type, action.data); + break; + default: + return; + } + } +}); + + +var FlowStore = new _FlowStore(); +AppDispatcher.register(FlowStore.handle.bind(FlowStore)); diff --git a/web/src/js/stores/settingstore.js b/web/src/js/stores/settingstore.js new file mode 100644 index 00000000..7eef9b8f --- /dev/null +++ b/web/src/js/stores/settingstore.js @@ -0,0 +1,28 @@ +function _SettingsStore() { + EventEmitter.call(this); + + //FIXME: What do we do if we haven't requested anything from the server yet? + this.settings = { + version: "0.12", + showEventLog: true, + mode: "transparent", + }; +} +_.extend(_SettingsStore.prototype, EventEmitter.prototype, { + getAll: function () { + return this.settings; + }, + handle: function (action) { + switch (action.type) { + case ActionTypes.UPDATE_SETTINGS: + this.settings = action.settings; + this.emit("change"); + break; + default: + return; + } + } +}); + +var SettingsStore = new _SettingsStore(); +AppDispatcher.register(SettingsStore.handle.bind(SettingsStore)); |