mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-26 02:10:59 +00:00
[web] finish utils/list
This commit is contained in:
parent
42f433e395
commit
a42512a1cc
@ -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 UPDATE:
|
||||
case WS_MSG:
|
||||
return {
|
||||
...state,
|
||||
list: reduceList(state.list, listActions.update(action))
|
||||
list: reduceList(state.list, listActions.handleWsMsg(action.msg))
|
||||
}
|
||||
|
||||
case REQUEST:
|
||||
return {
|
||||
...state,
|
||||
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 }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,166 +1,150 @@
|
||||
import {fetchApi} from "../../utils"
|
||||
import * as websocketActions from './websocket'
|
||||
|
||||
export const ADD = "ADD"
|
||||
export const UPDATE = "UPDATE"
|
||||
export const REMOVE = "REMOVE"
|
||||
export const REQUEST_LIST = "REQUEST_LIST"
|
||||
export const RECEIVE_LIST = "RECEIVE_LIST"
|
||||
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: {}
|
||||
}
|
||||
for (let i = 0; i < action.list.length; i++) {
|
||||
let item = action.list[i]
|
||||
s.byId[item.id] = item
|
||||
s.indexOf[item.id] = i
|
||||
}
|
||||
for (action of state.actionsDuringFetch) {
|
||||
s = reduceList(s, action)
|
||||
}
|
||||
return s
|
||||
} else if (state.isFetching) {
|
||||
switch (action.type) {
|
||||
|
||||
case UPDATE_FILTER:
|
||||
return {
|
||||
...state,
|
||||
actionsDuringFetch: [...state.actionsDuringFetch, action]
|
||||
[SYM_FILTER]: action.filter,
|
||||
data: state.raw.filter(action.filter).sort(state[SYM_SORTER]),
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
function addItem(item) {
|
||||
return {
|
||||
type: actionType,
|
||||
cmd: ADD,
|
||||
item
|
||||
}
|
||||
}
|
||||
|
||||
function updateItem(item) {
|
||||
return {
|
||||
type: actionType,
|
||||
cmd: UPDATE,
|
||||
item
|
||||
}
|
||||
}
|
||||
|
||||
function removeItem(item) {
|
||||
return {
|
||||
type: actionType,
|
||||
cmd: REMOVE,
|
||||
item
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
case UPDATE_SORTER:
|
||||
return {
|
||||
...state,
|
||||
[SYM_SORTER]: action.sorter,
|
||||
data: state.data.slice().sort(state[SYM_SORTER]),
|
||||
}
|
||||
}
|
||||
|
||||
case ADD:
|
||||
let data = state.data
|
||||
if (state[SYM_FILTER](action.item)) {
|
||||
data = [...state.data, action.item].sort(state[SYM_SORTER])
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
data,
|
||||
raw: [...state.raw, action.item],
|
||||
byId: { ...state.byId, [action.item.id]: action.item },
|
||||
}
|
||||
|
||||
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 },
|
||||
}
|
||||
|
||||
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 },
|
||||
}
|
||||
|
||||
case REQUEST:
|
||||
return {
|
||||
...state,
|
||||
isFetching: true,
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
function requestList() {
|
||||
return {
|
||||
type: actionType,
|
||||
cmd: REQUEST_LIST,
|
||||
}
|
||||
export function updateFilter(filter) {
|
||||
return { type: UPDATE_FILTER, filter }
|
||||
}
|
||||
|
||||
export function updateSorter(sorter) {
|
||||
return { type: UPDATE_SORTER, sorter }
|
||||
}
|
||||
|
||||
export function add(item) {
|
||||
return { type: ADD, item }
|
||||
}
|
||||
|
||||
export function update(id, item) {
|
||||
return { type: UPDATE, id, item }
|
||||
}
|
||||
|
||||
export function remove(id) {
|
||||
return { type: REMOVE, id }
|
||||
}
|
||||
|
||||
export function handleWsMsg(msg) {
|
||||
switch (msg.cmd) {
|
||||
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
function receiveList(list) {
|
||||
return {
|
||||
type: actionType,
|
||||
cmd: RECEIVE_LIST,
|
||||
list
|
||||
}
|
||||
}
|
||||
export function request() {
|
||||
return { type: REQUEST }
|
||||
}
|
||||
|
||||
function fetchList() {
|
||||
return dispatch => {
|
||||
export function receive(list) {
|
||||
return { type: RECEIVE, list }
|
||||
}
|
||||
|
||||
dispatch(requestList())
|
||||
|
||||
return fetchApi(fetchURL).then(response => {
|
||||
return response.json().then(json => {
|
||||
dispatch(receiveList(json.data))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return {reduceList, updateList, fetchList, addItem, updateItem, removeItem,}
|
||||
}
|
||||
export function fetchError(error) {
|
||||
return { type: FETCH_ERROR, error }
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user