diff options
Diffstat (limited to 'web/src/js')
| -rw-r--r-- | web/src/js/app.js | 17 | ||||
| -rw-r--r-- | web/src/js/components/eventlog.js | 69 | ||||
| -rw-r--r-- | web/src/js/connection.js | 4 | ||||
| -rw-r--r-- | web/src/js/ducks/eventLog.js | 32 | ||||
| -rw-r--r-- | web/src/js/ducks/flows.js | 15 | ||||
| -rw-r--r-- | web/src/js/ducks/index.js | 2 | ||||
| -rw-r--r-- | web/src/js/ducks/list.js | 21 | ||||
| -rw-r--r-- | web/src/js/ducks/websocket.js | 4 | 
8 files changed, 84 insertions, 80 deletions
| diff --git a/web/src/js/app.js b/web/src/js/app.js index f631b2c5..fc99f1d2 100644 --- a/web/src/js/app.js +++ b/web/src/js/app.js @@ -1,22 +1,25 @@  import React from "react"  import {render} from 'react-dom' -import {createStore} from 'redux' +import {applyMiddleware, createStore} from 'redux'  import {Provider} from 'react-redux' +import createLogger from 'redux-logger';  import Connection from "./connection"  import {App} from "./components/proxyapp.js" -import {EventLogActions} from "./actions.js"  import rootReducer from './ducks/index'; +import {addLogEntry} from "./ducks/eventLog"; -let store = createStore(rootReducer); +// logger must be last +const logger = createLogger(); +const store = createStore(rootReducer, applyMiddleware(logger)); + +window.onerror = function (msg) { +    store.dispatch(addLogEntry(msg)); +};  document.addEventListener('DOMContentLoaded', () => {      window.ws = new Connection("/updates", store.dispatch); -    window.onerror = function (msg) { -        EventLogActions.add_event(msg); -    }; -      render(          <Provider store={store}>{App}</Provider>,          document.getElementById("mitmproxy") diff --git a/web/src/js/components/eventlog.js b/web/src/js/components/eventlog.js index a2e6a0c1..0857056c 100644 --- a/web/src/js/components/eventlog.js +++ b/web/src/js/components/eventlog.js @@ -5,69 +5,57 @@ import shallowEqual from "shallowequal"  import {toggleEventLogFilter, toggleEventLogVisibility} from "../ducks/eventLog"  import AutoScroll from "./helpers/AutoScroll";  import {calcVScroll} from "./helpers/VirtualScroll" -import {StoreView} from "../store/view.js"  import {ToggleButton} from "./common"; -class EventLogContents extends React.Component { +function LogIcon({entry}) { +    let icon = {web: "html5", debug: "bug"}[entry.level] || "info"; +    return <i className={`fa fa-fw fa-${icon}`}></i> +} -    static contextTypes = { -        eventStore: React.PropTypes.object.isRequired, -    }; +function LogEntry({entry}) { +    return <div> +        <LogIcon entry={entry}/> +        {entry.message} +    </div>; +} + +class EventLogContents extends React.Component {      static defaultProps = {          rowHeight: 18,      }; -    constructor(props, context) { -        super(props, context); - -        this.view = new StoreView( -            this.context.eventStore, -            entry => this.props.filter[entry.level] -        ); +    constructor(props) { +        super(props);          this.heights = {}; -        this.state = {entries: this.view.list, vScroll: calcVScroll()}; +        this.state = {vScroll: calcVScroll()}; -        this.onChange = this.onChange.bind(this);          this.onViewportUpdate = this.onViewportUpdate.bind(this);      }      componentDidMount() {          window.addEventListener("resize", this.onViewportUpdate); -        this.view.addListener("add", this.onChange); -        this.view.addListener("recalculate", this.onChange);          this.onViewportUpdate();      }      componentWillUnmount() {          window.removeEventListener("resize", this.onViewportUpdate); -        this.view.removeListener("add", this.onChange); -        this.view.removeListener("recalculate", this.onChange); -        this.view.close();      }      componentDidUpdate() {          this.onViewportUpdate();      } -    componentWillReceiveProps(nextProps) { -        if (nextProps.filter !== this.props.filter) { -            this.view.recalculate( -                entry => nextProps.filter[entry.level] -            ); -        } -    } -      onViewportUpdate() {          const viewport = ReactDOM.findDOMNode(this);          const vScroll = calcVScroll({ -            itemCount: this.state.entries.length, +            itemCount: this.props.events.length,              rowHeight: this.props.rowHeight,              viewportTop: viewport.scrollTop,              viewportHeight: viewport.offsetHeight, -            itemHeights: this.state.entries.map(entry => this.heights[entry.id]), +            itemHeights: this.props.events.map(entry => this.heights[entry.id]),          });          if (!shallowEqual(this.state.vScroll, vScroll)) { @@ -75,10 +63,6 @@ class EventLogContents extends React.Component {          }      } -    onChange() { -        this.setState({entries: this.view.list}); -    } -      setHeight(id, ref) {          if (ref && !this.heights[id]) {              const height = ReactDOM.findDOMNode(ref).offsetHeight; @@ -89,23 +73,18 @@ class EventLogContents extends React.Component {          }      } -    getIcon(level) { -        return {web: "html5", debug: "bug"}[level] || "info"; -    } -      render() {          const vScroll = this.state.vScroll; -        const entries = this.state.entries.slice(vScroll.start, vScroll.end); +        const events = this.props.events +            .slice(vScroll.start, vScroll.end) +            .map(entry => +                <LogEntry entry={entry} key={entry.id} ref={this.setHeight.bind(this, entry.id)}/> +            );          return (              <pre onScroll={this.onViewportUpdate}>                  <div style={{ height: vScroll.paddingTop }}></div> -                {entries.map((entry, index) => ( -                    <div key={entry.id} ref={this.setHeight.bind(this, entry.id)}> -                        <i className={`fa fa-fw fa-${this.getIcon(entry.level)}`}></i> -                        {entry.message} -                    </div> -                ))} +                {events}                  <div style={{ height: vScroll.paddingBottom }}></div>              </pre>          ); @@ -117,7 +96,7 @@ EventLogContents = AutoScroll(EventLogContents);  const EventLogContentsContainer = connect(      state => ({ -        filter: state.eventLog.filter +        events: state.eventLog.filteredEvents      })  )(EventLogContents); diff --git a/web/src/js/connection.js b/web/src/js/connection.js index 71d20f46..75c2cf25 100644 --- a/web/src/js/connection.js +++ b/web/src/js/connection.js @@ -1,4 +1,3 @@ -  import {ConnectionActions, EventLogActions} from "./actions.js";  import {AppDispatcher} from "./dispatcher.js";  import * as websocketActions from "./ducks/websocket" @@ -12,11 +11,12 @@ export default function Connection(url, dispatch) {      ws.onopen = function () {          dispatch(websocketActions.connected());          ConnectionActions.open(); +        //TODO: fetch stuff!      };      ws.onmessage = function (m) {          var message = JSON.parse(m.data);          AppDispatcher.dispatchServerAction(message); -        dispatch(websocketActions.receiveMessage(message)); +        dispatch(message);      };      ws.onerror = function () {          ConnectionActions.error(); diff --git a/web/src/js/ducks/eventLog.js b/web/src/js/ducks/eventLog.js index 5bae252a..2040711c 100644 --- a/web/src/js/ducks/eventLog.js +++ b/web/src/js/ducks/eventLog.js @@ -1,5 +1,7 @@ +import getList, {ADD} from "./list"  const TOGGLE_FILTER = 'TOGGLE_EVENTLOG_FILTER'  const TOGGLE_VISIBILITY = 'TOGGLE_EVENTLOG_VISIBILITY' +const UPDATE_LIST = "UPDATE_EVENTLOG"  const defaultState = { @@ -8,23 +10,35 @@ const defaultState = {          "debug": false,          "info": true,          "web": true -    } +    }, +    events: getList(), +    filteredEvents: [],  } +  export default function reducer(state = defaultState, action) {      switch (action.type) {          case TOGGLE_FILTER: +            const filter = { +                ...state.filter, +                [action.filter]: !state.filter[action.filter] +            }              return {                  ...state, -                filter: { -                    ...state.filter, -                    [action.filter]: !state.filter[action.filter] -                } +                filter, +                filteredEvents: state.events.list.filter(x => filter[x.level])              }          case TOGGLE_VISIBILITY:              return {                  ...state,                  visible: !state.visible              } +        case UPDATE_LIST: +            const events = getList(state.events, action) +            return { +                ...state, +                events, +                filteredEvents: events.list.filter(x => state.filter[x.level]) +            }          default:              return state      } @@ -36,4 +50,12 @@ export function toggleEventLogFilter(filter) {  }  export function toggleEventLogVisibility() {      return {type: TOGGLE_VISIBILITY} +} +let id = 0; +export function addLogEntry(message, level = "web") { +    return { +        type: UPDATE_LIST, +        cmd: ADD, +        data: {message, level, id: `log-${id++}`} +    }  }
\ No newline at end of file diff --git a/web/src/js/ducks/flows.js b/web/src/js/ducks/flows.js deleted file mode 100644 index c4077f7a..00000000 --- a/web/src/js/ducks/flows.js +++ /dev/null @@ -1,15 +0,0 @@ -const defaultState = { -    list: [], -    isFetching: false, -    updateBeforeFetch: [], -    byId: {}, -    indexOf: {}, -    views: {} -} - -export default function reducer(state = defaultState, action) { -    switch (action.type) { -        default: -            return state -    } -} diff --git a/web/src/js/ducks/index.js b/web/src/js/ducks/index.js index 0074bda4..3043344c 100644 --- a/web/src/js/ducks/index.js +++ b/web/src/js/ducks/index.js @@ -1,11 +1,9 @@  import {combineReducers} from 'redux'  import eventLog from './eventLog.js'  import websocket from './websocket.js' -import flows from './flows.js'  const rootReducer = combineReducers({      eventLog, -    flows,      websocket,  }) diff --git a/web/src/js/ducks/list.js b/web/src/js/ducks/list.js new file mode 100644 index 00000000..0b3771e2 --- /dev/null +++ b/web/src/js/ducks/list.js @@ -0,0 +1,21 @@ +export const ADD = 'add' + +const defaultState = { +    list: [], +    //isFetching: false, +    //updateBeforeFetch: [], +    indexOf: {}, +    //views: {} +}; + +export default function getList(state = defaultState, action = {}) { +    switch (action.cmd) { +        case ADD: +            return { +                list: [...state.list, action.data], +                indexOf: {...state.indexOf, [action.data.id]: state.list.length}, +            } +        default: +            return state +    } +}
\ No newline at end of file diff --git a/web/src/js/ducks/websocket.js b/web/src/js/ducks/websocket.js index 281d1f2c..3999dbcf 100644 --- a/web/src/js/ducks/websocket.js +++ b/web/src/js/ducks/websocket.js @@ -1,6 +1,5 @@  const CONNECTED = 'WEBSOCKET_CONNECTED'  const DISCONNECTED = 'WEBSOCKET_DISCONNECTED' -const RECEIVE_MESSAGE = 'RECEIVE_WEBSOCKET_MESSAGE'  const defaultState = { @@ -28,7 +27,4 @@ export function connected() {  }  export function disconnected() {      return {type: DISCONNECTED} -} -export function receiveMessage(message) { -    return {type: RECEIVE_MESSAGE, message}  }
\ No newline at end of file | 
