diff options
| author | Jason <jason.daurus@gmail.com> | 2016-06-23 00:17:35 +0800 | 
|---|---|---|
| committer | Jason <jason.daurus@gmail.com> | 2016-06-23 00:17:35 +0800 | 
| commit | a42512a1cc1d84cd056d016bbcac9b1a66c3f05a (patch) | |
| tree | 18db46c82aa25efd04c90f9c46330d6e3ac72cea | |
| parent | 42f433e395beafbf8eab6d04a84a52580c5e8cda (diff) | |
| download | mitmproxy-a42512a1cc1d84cd056d016bbcac9b1a66c3f05a.tar.gz mitmproxy-a42512a1cc1d84cd056d016bbcac9b1a66c3f05a.tar.bz2 mitmproxy-a42512a1cc1d84cd056d016bbcac9b1a66c3f05a.zip  | |
[web] finish utils/list
| -rw-r--r-- | web/src/js/ducks/eventLog.js | 40 | ||||
| -rw-r--r-- | web/src/js/ducks/utils/list.js | 262 | ||||
| -rw-r--r-- | web/src/js/ducks/websocket.js | 4 | 
3 files changed, 153 insertions, 153 deletions
diff --git a/web/src/js/ducks/eventLog.js b/web/src/js/ducks/eventLog.js index 31dc82ea..86a9effb 100644 --- a/web/src/js/ducks/eventLog.js +++ b/web/src/js/ducks/eventLog.js @@ -1,15 +1,17 @@  import { fetchApi as fetch } from '../utils' +import { CMD_RESET as WS_CMD_RESET } from './websocket'  import reduceList, * as listActions from './utils/list' -export const TOGGLE_FILTER = 'EVENTLOG_TOGGLE_FILTER'  export const TOGGLE_VISIBILITY = 'EVENTLOG_TOGGLE_VISIBILITY' +export const TOGGLE_FILTER = 'EVENTLOG_TOGGLE_FILTER'  export const ADD = 'EVENTLOG_ADD' -export const UPDATE = 'EVENTLOG_UPDATE' +export const WS_MSG = 'EVENTLOG_WS_MSG'  export const REQUEST = 'EVENTLOG_REQUEST'  export const RECEIVE = 'EVENTLOG_RECEIVE'  export const ERROR = 'EVENTLOG_ERROR'  const defaultState = { +    logId: 0,      visible: false,      filters: { debug: false, info: true, web: true },      list: reduceList(undefined, { type: Symbol('EVENTLOG_INIT_LIST') }) @@ -32,19 +34,36 @@ export default function reduce(state = defaultState, action) {          case ADD:              return {                  ...state, -                list: reduceList(state.list, listActions.add({ message: action.message, level: action.level })) +                logId: state.logId + 1, +                list: reduceList(state.list, listActions.add({ +                    id: `log-${state.logId}`, +                    message: action.message, +                    level: action.level, +                })) +            } + +        case WS_MSG: +            return { +                ...state, +                list: reduceList(state.list, listActions.handleWsMsg(action.msg))              } -        case UPDATE: +        case REQUEST:              return {                  ...state, -                list: reduceList(state.list, listActions.update(action)) +                list: reduceList(state.list, listActions.request())              }          case RECEIVE:              return {                  ...state, -                list: reduceList(state.list, listActions.reset(action.list)) +                list: reduceList(state.list, listActions.receive(action.list)) +            } + +        case FETCH_ERROR: +            return { +                ...state, +                list: reduceList(state.list, listActions.fetchError(action.error))              }          default: @@ -84,14 +103,7 @@ export function handleWsMsg(msg) {      if (msg.cmd === WS_CMD_RESET) {          return fetch()      } -    return update(msg.cmd, msg.data) -} - -/** - * @private - */ -export function update(cmd, data) { -    return { type: UPDATE, cmd, data } +    return { type: WS_MSG, msg }  }  /** diff --git a/web/src/js/ducks/utils/list.js b/web/src/js/ducks/utils/list.js index a830fe99..1c1d9692 100644 --- a/web/src/js/ducks/utils/list.js +++ b/web/src/js/ducks/utils/list.js @@ -1,166 +1,150 @@ -import {fetchApi} from "../../utils" - -export const ADD = "ADD" -export const UPDATE = "UPDATE" -export const REMOVE = "REMOVE" -export const REQUEST_LIST = "REQUEST_LIST" -export const RECEIVE_LIST = "RECEIVE_LIST" - - +import * as websocketActions from './websocket' + +export const UPDATE_FILTER = 'LIST_UPDATE_FILTER' +export const UPDATE_SORTER = 'LIST_UPDATE_SORTER' +export const ADD = 'LIST_ADD' +export const UPDATE = 'LIST_UPDATE' +export const REMOVE = 'LIST_REMOVE' +export const UNKNOWN_CMD = 'LIST_UNKNOWN_CMD' +export const REQUEST = 'LIST_REQUEST' +export const RECEIVE = 'LIST_RECEIVE' +export const FETCH_ERROR = 'LIST_FETCH_ERROR' + +export const SYM_FILTER = Symbol('LIST_SYM_FILTER') +export const SYM_SORTER = Symbol('LIST_SYM_SORTER') +export const SYM_PENDING = Symbol('LIST_SYM_PENDING') + +// @todo add indexOf map if necessary  const defaultState = { -    list: [], -    isFetching: false, -    actionsDuringFetch: [], +    raw: [], +    data: [],      byId: {}, -    indexOf: {}, +    isFetching: false, +    [SYM_FILTER]: () => true, +    [SYM_SORTER]: () => 0, +    [SYM_PENDING]: [],  } -export default function makeList(actionType, fetchURL) { -    function reduceList(state = defaultState, action = {}) { - -        if (action.type !== actionType) { -            return state +export default function reduce(state = defaultState, action) { +    if (state.isFetching && action.type !== RECEIVE) { +        return { +            ...state, +            [SYM_PENDING]: [...state[SYM_PENDING], action]          } +    } -        // Handle cases where we finished fetching or are still fetching. -        if (action.cmd === RECEIVE_LIST) { -            let s = { -                isFetching: false, -                actionsDuringFetch: [], -                list: action.list, -                byId: {}, -                indexOf: {} +    switch (action.type) { + +        case UPDATE_FILTER: +            return { +                ...state, +                [SYM_FILTER]: action.filter, +                data: state.raw.filter(action.filter).sort(state[SYM_SORTER]),              } -            for (let i = 0; i < action.list.length; i++) { -                let item = action.list[i] -                s.byId[item.id] = item -                s.indexOf[item.id] = i + +        case UPDATE_SORTER: +            return { +                ...state, +                [SYM_SORTER]: action.sorter, +                data: state.data.slice().sort(state[SYM_SORTER]),              } -            for (action of state.actionsDuringFetch) { -                s = reduceList(s, action) + +        case ADD: +            let data = state.data +            if (state[SYM_FILTER](action.item)) { +                data = [...state.data, action.item].sort(state[SYM_SORTER])              } -            return s -        } else if (state.isFetching) {              return {                  ...state, -                actionsDuringFetch: [...state.actionsDuringFetch, action] +                data, +                raw: [...state.raw, action.item], +                byId: { ...state.byId, [action.item.id]: action.item },              } -        } -        let list, itemIndex -        switch (action.cmd) { -            case ADD: -                return { -                    list: [...state.list, action.item], -                    byId: {...state.byId, [action.item.id]: action.item}, -                    indexOf: {...state.indexOf, [action.item.id]: state.list.length}, -                } - -            case UPDATE: - -                list = [...state.list] -                itemIndex = state.indexOf[action.item.id] -                list[itemIndex] = action.item -                return { -                    ...state, -                    list, -                    byId: {...state.byId, [action.item.id]: action.item}, -                } - -            case REMOVE: -                list = [...state.list] -                itemIndex = state.indexOf[action.item.id] -                list.splice(itemIndex, 1) -                return { -                    ...state, -                    list, -                    byId: {...state.byId, [action.item.id]: undefined}, -                    indexOf: {...state.indexOf, [action.item.id]: undefined}, -                } - -            case REQUEST_LIST: -                return { -                    ...state, -                    isFetching: true -                } - -            default: -                console.debug("unknown action", action) -                return state -        } -    } +        case UPDATE: +            // @todo optimize if necessary +            const raw = state.raw.map(item => item.id === action.id ? action.item : item) +            return { +                ...state, +                raw, +                data: raw.filter(state[SYM_FILTER]).sort(state[SYM_SORTER]), +                byId: { ...state.byId, [action.id]: null, [action.item.id]: action.item }, +            } -    function addItem(item) { -        return { -            type: actionType, -            cmd: ADD, -            item -        } -    } +        case REMOVE: +            // @todo optimize if necessary +            return { +                ...state, +                raw: state.raw.filter(item => item.id !== action.id), +                data: state.data.filter(item => item.id !== action.id), +                byId: { ...state.byId, [action.id]: null }, +            } -    function updateItem(item) { -        return { -            type: actionType, -            cmd: UPDATE, -            item -        } -    } +        case REQUEST: +            return { +                ...state, +                isFetching: true, +            } -    function removeItem(item) { -        return { -            type: actionType, -            cmd: REMOVE, -            item -        } +        case RECEIVE: +            return { +                ...state, +                isFetching: false, +                raw: action.list, +                data: action.list.filter(state[SYM_FILTER]).sort(state[SYM_SORTER]), +                byId: _.fromPairs(action.list.map(item => [item.id, item])), +            } + +        default: +            return state      } +} +export function updateFilter(filter) { +    return { type: UPDATE_FILTER, filter } +} -    function updateList(event) { -        /* This action creater takes all WebSocket events */ -        return dispatch => { -            switch (event.cmd) { -                case "add": -                    return dispatch(addItem(event.data)) -                case "update": -                    return dispatch(updateItem(event.data)) -                case "remove": -                    return dispatch(removeItem(event.data)) -                case "reset": -                    return dispatch(fetchList()) -                default: -                    console.error("unknown list update", event) -            } -        } -    } +export function updateSorter(sorter) { +    return { type: UPDATE_SORTER, sorter } +} -    function requestList() { -        return { -            type: actionType, -            cmd: REQUEST_LIST, -        } -    } +export function add(item) { +    return { type: ADD, item } +} -    function receiveList(list) { -        return { -            type: actionType, -            cmd: RECEIVE_LIST, -            list -        } -    } +export function update(id, item) { +    return { type: UPDATE, id, item } +} -    function fetchList() { -        return dispatch => { +export function remove(id) { +    return { type: REMOVE, id } +} -            dispatch(requestList()) +export function handleWsMsg(msg) { +    switch (msg.cmd) { -            return fetchApi(fetchURL).then(response => { -                return response.json().then(json => { -                    dispatch(receiveList(json.data)) -                }) -            }) -        } +        case websocketActions.CMD_ADD: +            return add(msg.data) + +        case websocketActions.CMD_UPDATE: +            return update(msg.data.id, msg.data) + +        case websocketActions.CMD_REMOVE: +            return remove(msg.data.id) + +        default: +            return { type: UNKNOWN_CMD, msg }      } +} +export function request() { +    return { type: REQUEST } +} + +export function receive(list) { +    return { type: RECEIVE, list } +} -    return {reduceList, updateList, fetchList, addItem, updateItem, removeItem,} -}
\ No newline at end of file +export function fetchError(error) { +    return { type: FETCH_ERROR, error } +} diff --git a/web/src/js/ducks/websocket.js b/web/src/js/ducks/websocket.js index ebb39cf8..c10f9f5e 100644 --- a/web/src/js/ducks/websocket.js +++ b/web/src/js/ducks/websocket.js @@ -1,6 +1,10 @@  const CONNECTED = 'WEBSOCKET_CONNECTED'  const DISCONNECTED = 'WEBSOCKET_DISCONNECTED' +export const CMD_ADD = 'add' +export const CMD_UPDATE = 'update' +export const CMD_REMOVE = 'remove' +export const CMD_RESET = 'reset'  const defaultState = {      connected: false,  | 
