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, |