aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaximilian Hils <git@maximilianhils.com>2014-09-16 00:05:06 +0200
committerMaximilian Hils <git@maximilianhils.com>2014-09-16 00:05:06 +0200
commitacdd182754625fabcfc2c6ed4bdad8a63bce8ad6 (patch)
treebd48b8c269790d31913a13ecac8969c9d6413f0e
parent1d9b1f79a11feb57043be1d9d656f4c1638d3357 (diff)
downloadmitmproxy-acdd182754625fabcfc2c6ed4bdad8a63bce8ad6.tar.gz
mitmproxy-acdd182754625fabcfc2c6ed4bdad8a63bce8ad6.tar.bz2
mitmproxy-acdd182754625fabcfc2c6ed4bdad8a63bce8ad6.zip
web: implement EventLogStore
-rw-r--r--libmproxy/web/static/js/app.js253
-rw-r--r--web/.jshintrc3
-rw-r--r--web/gulpfile.js1
-rw-r--r--web/src/js/Connection.es6.js23
-rw-r--r--web/src/js/Dispatcher.es6.js4
-rw-r--r--web/src/js/actions.es6.js7
-rw-r--r--web/src/js/app.js1
-rw-r--r--web/src/js/components/EventLog.react.js21
-rw-r--r--web/src/js/components/Header.react.js14
-rw-r--r--web/src/js/components/ProxyApp.react.js16
-rw-r--r--web/src/js/components/TrafficTable.react.js33
-rw-r--r--web/src/js/stores/EventLogStore.es6.js79
-rw-r--r--web/src/js/stores/SettingsStore.es6.js23
-rw-r--r--web/src/js/stores/base.es6.js2
14 files changed, 264 insertions, 216 deletions
diff --git a/libmproxy/web/static/js/app.js b/libmproxy/web/static/js/app.js
index 72bb5ff8..92d6c4c8 100644
--- a/libmproxy/web/static/js/app.js
+++ b/libmproxy/web/static/js/app.js
@@ -34,14 +34,21 @@ AppDispatcher.dispatchViewAction = function(action){
action.actionSource = PayloadSources.VIEW_ACTION;
this.dispatch(action);
};
+AppDispatcher.dispatchServerAction = function(action){
+ action.actionSource = PayloadSources.SERVER_ACTION;
+ this.dispatch(action);
+};
var ActionTypes = {
SETTINGS_UPDATE: "SETTINGS_UPDATE",
- LOG_ADD: "LOG_ADD"
+ EVENTLOG_ADD: "EVENTLOG_ADD"
};
var SettingsActions = {
update:function(settings) {
- settings = _.merge({}, SettingsStore.getSettings(), settings);
+ settings = _.merge({}, SettingsStore.getAll(), settings);
+ //TODO: Update server.
+
+ //Facebook Flux: We do an optimistic update on the client already.
AppDispatcher.dispatchViewAction({
actionType: ActionTypes.SETTINGS_UPDATE,
settings: settings
@@ -57,7 +64,7 @@ var SettingsActions = {
return;
}
this.listeners[event].forEach(function(listener) {
- listener(event, this);
+ listener.apply(this, arguments);
}.bind(this));
};
EventEmitter.prototype.addListener=function(event, f) {"use strict";
@@ -76,11 +83,10 @@ var SettingsActions = {
for(var EventEmitter____Key in EventEmitter){if(EventEmitter.hasOwnProperty(EventEmitter____Key)){_SettingsStore[EventEmitter____Key]=EventEmitter[EventEmitter____Key];}}var ____SuperProtoOfEventEmitter=EventEmitter===null?null:EventEmitter.prototype;_SettingsStore.prototype=Object.create(____SuperProtoOfEventEmitter);_SettingsStore.prototype.constructor=_SettingsStore;_SettingsStore.__superConstructor__=EventEmitter;
function _SettingsStore() {"use strict";
- /*jshint validthis: true */
EventEmitter.call(this);
this.settings = { version: "0.12", showEventLog: true }; //FIXME: Need to get that from somewhere.
}
- _SettingsStore.prototype.getSettings=function() {"use strict";
+ _SettingsStore.prototype.getAll=function() {"use strict";
return this.settings;
};
_SettingsStore.prototype.handle=function(action) {"use strict";
@@ -97,39 +103,65 @@ for(var EventEmitter____Key in EventEmitter){if(EventEmitter.hasOwnProperty(Even
var SettingsStore = new _SettingsStore();
AppDispatcher.register(SettingsStore.handle.bind(SettingsStore));
-
-var SettingsMixin = {
- getInitialState:function(){
- return {
- settings: SettingsStore.getSettings()
- };
- },
- componentDidMount:function(){
- SettingsStore.addListener("change", this._onSettingsChange);
- },
- componentWillUnmount:function(){
- SettingsStore.removeListener("change", this._onSettingsChange);
- },
- _onSettingsChange:function(){
- this.setState({
- settings: SettingsStore.getSettings()
- });
- }
-};
-for(var EventEmitter____Key in EventEmitter){if(EventEmitter.hasOwnProperty(EventEmitter____Key)){_EventLogStore[EventEmitter____Key]=EventEmitter[EventEmitter____Key];}}var ____SuperProtoOfEventEmitter=EventEmitter===null?null:EventEmitter.prototype;_EventLogStore.prototype=Object.create(____SuperProtoOfEventEmitter);_EventLogStore.prototype.constructor=_EventLogStore;_EventLogStore.__superConstructor__=EventEmitter;
- function _EventLogStore() {"use strict";
- /*jshint validthis: true */
+for(var EventEmitter____Key in EventEmitter){if(EventEmitter.hasOwnProperty(EventEmitter____Key)){EventLogView[EventEmitter____Key]=EventEmitter[EventEmitter____Key];}}var ____SuperProtoOfEventEmitter=EventEmitter===null?null:EventEmitter.prototype;EventLogView.prototype=Object.create(____SuperProtoOfEventEmitter);EventLogView.prototype.constructor=EventLogView;EventLogView.__superConstructor__=EventEmitter;
+ function EventLogView(store, live){"use strict";
EventEmitter.call(this);
+ this.$EventLogView_store = store;
+ this.live = live;
this.log = [];
+
+ this.add = this.add.bind(this);
+
+ if(live){
+ this.$EventLogView_store.addListener("new_entry", this.add);
+ }
+
}
- _EventLogStore.prototype.getAll=function() {"use strict";
+ EventLogView.prototype.close=function() {"use strict";
+ this.$EventLogView_store.removeListener("new_entry", this.add);
+ };
+ EventLogView.prototype.getAll=function() {"use strict";
return this.log;
};
+
+ EventLogView.prototype.add=function(entry){"use strict";
+ this.log.push(entry);
+ this.emit("change");
+ };
+ EventLogView.prototype.add_bulk=function(messages){"use strict";
+ 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");
+ };
+
+
+for(EventEmitter____Key in EventEmitter){if(EventEmitter.hasOwnProperty(EventEmitter____Key)){_EventLogStore[EventEmitter____Key]=EventEmitter[EventEmitter____Key];}}_EventLogStore.prototype=Object.create(____SuperProtoOfEventEmitter);_EventLogStore.prototype.constructor=_EventLogStore;_EventLogStore.__superConstructor__=EventEmitter;function _EventLogStore(){"use strict";if(EventEmitter!==null){EventEmitter.apply(this,arguments);}}
+ _EventLogStore.prototype.getView=function(since){"use strict";
+ var view = new EventLogView(this, !since);
+
+ //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;
+ };
_EventLogStore.prototype.handle=function(action) {"use strict";
switch (action.actionType) {
- case ActionTypes.LOG_ADD:
- this.log.push(action.message);
- this.emit("change");
+ case ActionTypes.EVENTLOG_ADD:
+ this.emit("new_message", action.message);
break;
default:
return;
@@ -139,70 +171,19 @@ for(var EventEmitter____Key in EventEmitter){if(EventEmitter.hasOwnProperty(Even
var EventLogStore = new _EventLogStore();
AppDispatcher.register(EventLogStore.handle.bind(EventLogStore));
-
-var EventLogMixin = {
- getInitialState:function(){
- return {
- log: EventLog.getAll()
- };
- },
- componentDidMount:function(){
- SettingsStore.addListener("change", this._onEventLogChange);
- },
- componentWillUnmount:function(){
- SettingsStore.removeListener("change", this._onEventLogChange);
- },
- _onEventLogChange:function(){
- this.setState({
- log: EventLog.getAll()
- });
- }
-};
-
- function Connection(root){"use strict";
- if(!root){
+ function _Connection(root) {"use strict";
+ if (!root) {
root = location.origin + "/api/v1";
}
this.root = root;
- this.openWebSocketConnection();
}
- Connection.prototype.openWebSocketConnection=function(){"use strict";
- this.ws = new WebSocket(this.root.replace("http","ws") + "/ws");
- var ws = this.ws;
-
- ws.onopen = this.onopen.bind(this);
- ws.onmessage = this.onmessage.bind(this);
- ws.onerror = this.onerror.bind(this);
- ws.onclose = this.onclose.bind(this);
- };
-
- Connection.prototype.onopen=function(open){"use strict";
- console.log("onopen", this, arguments);
- };
- Connection.prototype.onmessage=function(message){"use strict";
- console.log("onmessage", this, arguments);
- };
- Connection.prototype.onerror=function(error){"use strict";
- console.log("onerror", this, arguments);
- };
- Connection.prototype.onclose=function(close){"use strict";
- console.log("onclose", this, arguments);
- };
-
-
-
-
- function Connection(root){"use strict";
- if(!root){
- root = location.origin + "/api/v1";
- }
- this.root = root;
+ _Connection.prototype.init=function() {"use strict";
this.openWebSocketConnection();
- }
+ };
- Connection.prototype.openWebSocketConnection=function(){"use strict";
- this.ws = new WebSocket(this.root.replace("http","ws") + "/ws");
+ _Connection.prototype.openWebSocketConnection=function() {"use strict";
+ this.ws = new WebSocket(this.root.replace("http", "ws") + "/ws");
var ws = this.ws;
ws.onopen = this.onopen.bind(this);
@@ -211,33 +192,33 @@ var EventLogMixin = {
ws.onclose = this.onclose.bind(this);
};
- Connection.prototype.onopen=function(open){"use strict";
+ _Connection.prototype.onopen=function(open) {"use strict";
console.log("onopen", this, arguments);
};
- Connection.prototype.onmessage=function(message){"use strict";
+ _Connection.prototype.onmessage=function(message) {"use strict";
+ //AppDispatcher.dispatchServerAction(...);
console.log("onmessage", this, arguments);
};
- Connection.prototype.onerror=function(error){"use strict";
+ _Connection.prototype.onerror=function(error) {"use strict";
console.log("onerror", this, arguments);
};
- Connection.prototype.onclose=function(close){"use strict";
+ _Connection.prototype.onclose=function(close) {"use strict";
console.log("onclose", this, arguments);
};
-
+var Connection = new _Connection();
/** @jsx React.DOM */
var MainMenu = React.createClass({displayName: 'MainMenu',
- mixins: [SettingsMixin],
- handleSettingsChange:function() {
+ toggleEventLog:function() {
SettingsActions.update({
- showEventLog: !this.state.settings.showEventLog
+ showEventLog: !this.props.settings.showEventLog
});
},
render:function(){
return React.DOM.div(null,
- React.DOM.button({className: "btn " + (this.state.settings.showEventLog ? "btn-primary" : "btn-default"), onClick: this.handleSettingsChange},
+ React.DOM.button({className: "btn " + (this.props.settings.showEventLog ? "btn-primary" : "btn-default"), onClick: this.toggleEventLog},
React.DOM.i({className: "fa fa-database"}), " Display Event Log"
)
);
@@ -274,7 +255,6 @@ var _Header_Entries = {
};
var Header = React.createClass({displayName: 'Header',
- mixins: [SettingsMixin],
getInitialState:function(){
return {
active: "main"
@@ -297,11 +277,13 @@ var Header = React.createClass({displayName: 'Header',
onClick: this.handleClick.bind(this, item)}, _Header_Entries[item].title));
}
- var menu = _Header_Entries[this.state.active].menu();
+ var menu = _Header_Entries[this.state.active].menu({
+ settings: this.props.settings
+ });
return (
React.DOM.header(null,
React.DOM.div({className: "title-bar"},
- "mitmproxy ", this.state.settings.version
+ "mitmproxy ", this.props.settings.version
),
React.DOM.nav(null,
React.DOM.a({href: "#", className: "special", onClick: this.handleFileClick}, " File "),
@@ -316,36 +298,29 @@ var Header = React.createClass({displayName: 'Header',
/** @jsx React.DOM */
var TrafficTable = React.createClass({displayName: 'TrafficTable',
- /*getInitialState: function(){
+ getInitialState: function(){
return {
flows: []
};
- },*/
- componentDidMount: function () {
- /*var flowStore = new DummyFlowStore([]);
- this.setState({flowStore: flowStore});
-
- flowStore.addChangeListener(this.onFlowsChange);
-
- $.getJSON("/flows.json").success(function (flows) {
- flows.forEach(function (flow, i) {
- window.setTimeout(function () {
- flowStore.addFlow(flow);
- }, _.random(i*400,i*400+1000));
- });
- }.bind(this));*/
},
- componentWillUnmount: function(){
- //this.state.flowStore.close();
+ componentDidMount:function(){
+ //this.flowStore = FlowStore.getView();
+ //this.flowStore.addListener("change",this.onFlowChange);
+ },
+ componentWillUnmount:function(){
+ //this.flowStore.removeListener("change",this.onFlowChange);
+ //this.flowStore.close();
},
- onFlowsChange: function(event, flows){
- //this.setState({flows: flows.getAll()});
+ onFlowChange:function(){
+ this.setState({
+ //flows: this.flowStore.getAll()
+ });
},
render: function () {
/*var flows = this.state.flows.map(function(flow){
return <div>{flow.request.method} {flow.request.scheme}://{flow.request.host}{flow.request.path}</div>;
}); *//**/
- x = "WTF";
+ x = "Flow";
i = 12;
while(i--) x += x;
return React.DOM.div(null, React.DOM.pre(null, x));
@@ -354,17 +329,36 @@ var TrafficTable = React.createClass({displayName: 'TrafficTable',
/** @jsx React.DOM */
var EventLog = React.createClass({displayName: 'EventLog',
+ getInitialState:function(){
+ return {
+ log: []
+ };
+ },
+ componentDidMount:function(){
+ this.log = EventLogStore.getView();
+ this.log.addListener("change",this.onEventLogChange);
+ },
+ componentWillUnmount:function(){
+ this.log.removeListener("change",this.onEventLogChange);
+ this.log.close();
+ },
+ onEventLogChange:function(){
+ this.setState({
+ log: this.log.getAll()
+ });
+ },
close:function(){
SettingsActions.update({
showEventLog: false
});
},
render:function(){
+ var messages = this.state.log.map(function(row) {return React.DOM.div({key: row.id}, row.message);});
return (
React.DOM.div({className: "eventlog"},
React.DOM.pre(null,
React.DOM.i({className: "fa fa-close close-button", onClick: this.close}),
- "much log."
+ messages
)
)
);
@@ -393,11 +387,23 @@ var Reports = React.createClass({displayName: 'Reports',
var ProxyAppMain = React.createClass({displayName: 'ProxyAppMain',
- mixins: [SettingsMixin],
+ getInitialState:function(){
+ return { settings: SettingsStore.getAll() };
+ },
+ componentDidMount:function(){
+ SettingsStore.addListener("change", this.onSettingsChange);
+ },
+ componentWillUnmount:function(){
+ SettingsStore.removeListener("change", this.onSettingsChange);
+ },
+ onSettingsChange:function(){
+ console.log("onSettingsChange");
+ this.setState({settings: SettingsStore.getAll()});
+ },
render:function() {
return (
React.DOM.div({id: "container"},
- Header(null),
+ Header({settings: this.state.settings}),
React.DOM.div({id: "main"}, this.props.activeRouteHandler(null)),
this.state.settings.showEventLog ? EventLog(null) : null,
Footer(null)
@@ -419,6 +425,7 @@ var ProxyApp = (
$(function(){
+ Connection.init();
app = React.renderComponent(ProxyApp, document.body);
});
diff --git a/web/.jshintrc b/web/.jshintrc
index acdf04d3..d5eae073 100644
--- a/web/.jshintrc
+++ b/web/.jshintrc
@@ -1,4 +1,5 @@
{
"loopfunc": true,
- "esnext": true
+ "esnext": true,
+ "validthis": true
} \ No newline at end of file
diff --git a/web/gulpfile.js b/web/gulpfile.js
index 939f4fcc..3aebcd95 100644
--- a/web/gulpfile.js
+++ b/web/gulpfile.js
@@ -38,7 +38,6 @@ var path = {
'js/stores/SettingsStore.es6.js',
'js/stores/EventLogStore.es6.js',
'js/Connection.es6.js',
- 'js/connection.es6.js',
'js/components/Header.react.js',
'js/components/TrafficTable.react.js',
'js/components/EventLog.react.js',
diff --git a/web/src/js/Connection.es6.js b/web/src/js/Connection.es6.js
index 9daa82e2..05d86c93 100644
--- a/web/src/js/Connection.es6.js
+++ b/web/src/js/Connection.es6.js
@@ -1,14 +1,17 @@
-class Connection {
- constructor(root){
- if(!root){
+class _Connection {
+ constructor(root) {
+ if (!root) {
root = location.origin + "/api/v1";
}
this.root = root;
+ }
+
+ init() {
this.openWebSocketConnection();
}
- openWebSocketConnection(){
- this.ws = new WebSocket(this.root.replace("http","ws") + "/ws");
+ openWebSocketConnection() {
+ this.ws = new WebSocket(this.root.replace("http", "ws") + "/ws");
var ws = this.ws;
ws.onopen = this.onopen.bind(this);
@@ -17,17 +20,19 @@ class Connection {
ws.onclose = this.onclose.bind(this);
}
- onopen(open){
+ onopen(open) {
console.log("onopen", this, arguments);
}
- onmessage(message){
+ onmessage(message) {
+ //AppDispatcher.dispatchServerAction(...);
console.log("onmessage", this, arguments);
}
- onerror(error){
+ onerror(error) {
console.log("onerror", this, arguments);
}
- onclose(close){
+ onclose(close) {
console.log("onclose", this, arguments);
}
}
+var Connection = new _Connection(); \ No newline at end of file
diff --git a/web/src/js/Dispatcher.es6.js b/web/src/js/Dispatcher.es6.js
index 9bf70878..6ac17f9f 100644
--- a/web/src/js/Dispatcher.es6.js
+++ b/web/src/js/Dispatcher.es6.js
@@ -33,4 +33,8 @@ AppDispatcher = new Dispatcher();
AppDispatcher.dispatchViewAction = function(action){
action.actionSource = PayloadSources.VIEW_ACTION;
this.dispatch(action);
+};
+AppDispatcher.dispatchServerAction = function(action){
+ action.actionSource = PayloadSources.SERVER_ACTION;
+ this.dispatch(action);
}; \ No newline at end of file
diff --git a/web/src/js/actions.es6.js b/web/src/js/actions.es6.js
index b6770074..6b3a5870 100644
--- a/web/src/js/actions.es6.js
+++ b/web/src/js/actions.es6.js
@@ -1,11 +1,14 @@
var ActionTypes = {
SETTINGS_UPDATE: "SETTINGS_UPDATE",
- LOG_ADD: "LOG_ADD"
+ EVENTLOG_ADD: "EVENTLOG_ADD"
};
var SettingsActions = {
update(settings) {
- settings = _.merge({}, SettingsStore.getSettings(), settings);
+ settings = _.merge({}, SettingsStore.getAll(), settings);
+ //TODO: Update server.
+
+ //Facebook Flux: We do an optimistic update on the client already.
AppDispatcher.dispatchViewAction({
actionType: ActionTypes.SETTINGS_UPDATE,
settings: settings
diff --git a/web/src/js/app.js b/web/src/js/app.js
index 2e4557af..2049ef25 100644
--- a/web/src/js/app.js
+++ b/web/src/js/app.js
@@ -1,5 +1,6 @@
$(function(){
+ Connection.init();
app = React.renderComponent(ProxyApp, document.body);
}); \ No newline at end of file
diff --git a/web/src/js/components/EventLog.react.js b/web/src/js/components/EventLog.react.js
index 0ecf40b1..3a7dedc8 100644
--- a/web/src/js/components/EventLog.react.js
+++ b/web/src/js/components/EventLog.react.js
@@ -1,17 +1,36 @@
/** @jsx React.DOM */
var EventLog = React.createClass({
+ getInitialState(){
+ return {
+ log: []
+ };
+ },
+ componentDidMount(){
+ this.log = EventLogStore.getView();
+ this.log.addListener("change",this.onEventLogChange);
+ },
+ componentWillUnmount(){
+ this.log.removeListener("change",this.onEventLogChange);
+ this.log.close();
+ },
+ onEventLogChange(){
+ this.setState({
+ log: this.log.getAll()
+ });
+ },
close(){
SettingsActions.update({
showEventLog: false
});
},
render(){
+ var messages = this.state.log.map(row => <div key={row.id}>{row.message}</div>);
return (
<div className="eventlog">
<pre>
<i className="fa fa-close close-button" onClick={this.close}></i>
- much log.
+ {messages}
</pre>
</div>
);
diff --git a/web/src/js/components/Header.react.js b/web/src/js/components/Header.react.js
index d1f18a82..41202463 100644
--- a/web/src/js/components/Header.react.js
+++ b/web/src/js/components/Header.react.js
@@ -1,15 +1,14 @@
/** @jsx React.DOM */
var MainMenu = React.createClass({
- mixins: [SettingsMixin],
- handleSettingsChange() {
+ toggleEventLog() {
SettingsActions.update({
- showEventLog: !this.state.settings.showEventLog
+ showEventLog: !this.props.settings.showEventLog
});
},
render(){
return <div>
- <button className={"btn " + (this.state.settings.showEventLog ? "btn-primary" : "btn-default")} onClick={this.handleSettingsChange}>
+ <button className={"btn " + (this.props.settings.showEventLog ? "btn-primary" : "btn-default")} onClick={this.toggleEventLog}>
<i className="fa fa-database"></i> Display Event Log
</button>
</div>;
@@ -46,7 +45,6 @@ var _Header_Entries = {
};
var Header = React.createClass({
- mixins: [SettingsMixin],
getInitialState(){
return {
active: "main"
@@ -69,11 +67,13 @@ var Header = React.createClass({
onClick={this.handleClick.bind(this, item)}>{ _Header_Entries[item].title }</a>);
}
- var menu = _Header_Entries[this.state.active].menu();
+ var menu = _Header_Entries[this.state.active].menu({
+ settings: this.props.settings
+ });
return (
<header>
<div className="title-bar">
- mitmproxy { this.state.settings.version }
+ mitmproxy { this.props.settings.version }
</div>
<nav>
<a href="#" className="special" onClick={this.handleFileClick}> File </a>
diff --git a/web/src/js/components/ProxyApp.react.js b/web/src/js/components/ProxyApp.react.js
index 7953d938..fc21ecd8 100644
--- a/web/src/js/components/ProxyApp.react.js
+++ b/web/src/js/components/ProxyApp.react.js
@@ -10,11 +10,23 @@ var Reports = React.createClass({
var ProxyAppMain = React.createClass({
- mixins: [SettingsMixin],
+ getInitialState(){
+ return { settings: SettingsStore.getAll() };
+ },
+ componentDidMount(){
+ SettingsStore.addListener("change", this.onSettingsChange);
+ },
+ componentWillUnmount(){
+ SettingsStore.removeListener("change", this.onSettingsChange);
+ },
+ onSettingsChange(){
+ console.log("onSettingsChange");
+ this.setState({settings: SettingsStore.getAll()});
+ },
render() {
return (
<div id="container">
- <Header/>
+ <Header settings={this.state.settings}/>
<div id="main"><this.props.activeRouteHandler/></div>
{this.state.settings.showEventLog ? <EventLog/> : null}
<Footer/>
diff --git a/web/src/js/components/TrafficTable.react.js b/web/src/js/components/TrafficTable.react.js
index 442f8da2..d6a4f200 100644
--- a/web/src/js/components/TrafficTable.react.js
+++ b/web/src/js/components/TrafficTable.react.js
@@ -1,36 +1,29 @@
/** @jsx React.DOM */
var TrafficTable = React.createClass({
- /*getInitialState: function(){
+ getInitialState: function(){
return {
flows: []
};
- },*/
- componentDidMount: function () {
- /*var flowStore = new DummyFlowStore([]);
- this.setState({flowStore: flowStore});
-
- flowStore.addChangeListener(this.onFlowsChange);
-
- $.getJSON("/flows.json").success(function (flows) {
- flows.forEach(function (flow, i) {
- window.setTimeout(function () {
- flowStore.addFlow(flow);
- }, _.random(i*400,i*400+1000));
- });
- }.bind(this));*/
},
- componentWillUnmount: function(){
- //this.state.flowStore.close();
+ componentDidMount(){
+ //this.flowStore = FlowStore.getView();
+ //this.flowStore.addListener("change",this.onFlowChange);
+ },
+ componentWillUnmount(){
+ //this.flowStore.removeListener("change",this.onFlowChange);
+ //this.flowStore.close();
},
- onFlowsChange: function(event, flows){
- //this.setState({flows: flows.getAll()});
+ onFlowChange(){
+ this.setState({
+ //flows: this.flowStore.getAll()
+ });
},
render: function () {
/*var flows = this.state.flows.map(function(flow){
return <div>{flow.request.method} {flow.request.scheme}://{flow.request.host}{flow.request.path}</div>;
}); *//**/
- x = "WTF";
+ x = "Flow";
i = 12;
while(i--) x += x;
return <div><pre>{x}</pre></div>;
diff --git a/web/src/js/stores/EventLogStore.es6.js b/web/src/js/stores/EventLogStore.es6.js
index caa9d77d..55401690 100644
--- a/web/src/js/stores/EventLogStore.es6.js
+++ b/web/src/js/stores/EventLogStore.es6.js
@@ -1,17 +1,62 @@
-class _EventLogStore extends EventEmitter {
- constructor() {
- /*jshint validthis: true */
+class EventLogView extends EventEmitter {
+ constructor(store, live){
super();
+ this._store = store;
+ this.live = live;
this.log = [];
+
+ this.add = this.add.bind(this);
+
+ if(live){
+ this._store.addListener("new_entry", this.add);
+ }
+
+ }
+ close() {
+ this._store.removeListener("new_entry", this.add);
}
getAll() {
return this.log;
}
+
+ add(entry){
+ this.log.push(entry);
+ this.emit("change");
+ }
+ add_bulk(messages){
+ var log = messages;
+ var last_id = log[log.length-1].id;
+ var to_add = _.filter(this.log, entry => entry.id > last_id);
+ this.log = log.concat(to_add);
+ this.emit("change");
+ }
+}
+
+class _EventLogStore extends EventEmitter {
+ getView(since){
+ var view = new EventLogView(this, !since);
+
+ //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(action) {
switch (action.actionType) {
- case ActionTypes.LOG_ADD:
- this.log.push(action.message);
- this.emit("change");
+ case ActionTypes.EVENTLOG_ADD:
+ this.emit("new_message", action.message);
break;
default:
return;
@@ -19,24 +64,4 @@ class _EventLogStore extends EventEmitter {
}
}
var EventLogStore = new _EventLogStore();
-AppDispatcher.register(EventLogStore.handle.bind(EventLogStore));
-
-
-var EventLogMixin = {
- getInitialState(){
- return {
- log: EventLog.getAll()
- };
- },
- componentDidMount(){
- SettingsStore.addListener("change", this._onEventLogChange);
- },
- componentWillUnmount(){
- SettingsStore.removeListener("change", this._onEventLogChange);
- },
- _onEventLogChange(){
- this.setState({
- log: EventLog.getAll()
- });
- }
-}; \ No newline at end of file
+AppDispatcher.register(EventLogStore.handle.bind(EventLogStore)); \ No newline at end of file
diff --git a/web/src/js/stores/SettingsStore.es6.js b/web/src/js/stores/SettingsStore.es6.js
index 7f3a6837..dea4597c 100644
--- a/web/src/js/stores/SettingsStore.es6.js
+++ b/web/src/js/stores/SettingsStore.es6.js
@@ -1,10 +1,9 @@
class _SettingsStore extends EventEmitter {
constructor() {
- /*jshint validthis: true */
super();
this.settings = { version: "0.12", showEventLog: true }; //FIXME: Need to get that from somewhere.
}
- getSettings() {
+ getAll() {
return this.settings;
}
handle(action) {
@@ -20,23 +19,3 @@ class _SettingsStore extends EventEmitter {
}
var SettingsStore = new _SettingsStore();
AppDispatcher.register(SettingsStore.handle.bind(SettingsStore));
-
-
-var SettingsMixin = {
- getInitialState(){
- return {
- settings: SettingsStore.getSettings()
- };
- },
- componentDidMount(){
- SettingsStore.addListener("change", this._onSettingsChange);
- },
- componentWillUnmount(){
- SettingsStore.removeListener("change", this._onSettingsChange);
- },
- _onSettingsChange(){
- this.setState({
- settings: SettingsStore.getSettings()
- });
- }
-}; \ No newline at end of file
diff --git a/web/src/js/stores/base.es6.js b/web/src/js/stores/base.es6.js
index 9e9c69aa..d5d0c7ab 100644
--- a/web/src/js/stores/base.es6.js
+++ b/web/src/js/stores/base.es6.js
@@ -7,7 +7,7 @@ class EventEmitter {
return;
}
this.listeners[event].forEach(function(listener) {
- listener(event, this);
+ listener.apply(this, arguments);
}.bind(this));
}
addListener(event, f) {