//TODO: Move into some utils .monospace() { font-family: Menlo, Monaco, Consolas, "Courier New", monospace; } .flow-detail { width: 100%; overflow:hidden; display: flex; flex-direction: column; nav { background-color: #F2F2F2; } section { overflow-y: scroll; >article{ overflow: auto; padding: 5px 12px 0; } >footer { box-shadow: 0 0 3px gray; padding: 2px; margin: 0; height:23px; } } section.detail, section.error{ overflow: auto; padding: 5px 12px 0; } .first-line { .monospace(); background-color: #428bca; color: white; margin: 0 -8px; padding: 4px 8px; border-radius: 5px; word-break: break-all; max-height: 100px; overflow-y: auto; .inline-input.editable { border-color: rgba(255,255,255,0.5); } } .request-line { margin-bottom: 2px; } hr { margin: 0 0 5px; } } .inline-input { display: inline; margin: 0 -3px; padding: 0 3px; border: solid transparent 1px; &.editable { border-color: #ccc; } &[contenteditable] { background-color: rgba(255, 255, 255, 0.2); &.has-warning { color: rgb(255, 184, 184); } &.has-success { //color: green; } } } .view-all-content-btn{ float: right; margin-bottom: 12px; } .flow-detail table { .monospace(); width: 100%; table-layout: fixed; word-break: break-all; tr { &:not(:first-child) { border-top: 1px solid #f7f7f7; } } td { vertical-align: top; //alt: //white-space: nowrap; //overflow: hidden; //text-overflow: ellipsis; } } .connection-table { td:first-child { width: 50%; padding-right: 1em; } } .header-table { td { line-height: 1.3em; } .header-name { width: 33%; } .header-value { } // This exists so that you can copy // and paste headers out of mitmweb. .header-colon { position: absolute; opacity: 0; } .inline-input { display: inline-block; width: 100%; height: 100%; } } .connection-table, .timing-table { td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } } th'>path: root/web/src/js/ducks/msgQueue.js
blob: 6d82f4c22eeed941d48e7d19ea5c5e2bf9fb1b71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { fetchApi } from '../utils'
import * as websocketActions from './websocket'
import * as eventLogActions from './eventLog'
import * as flowsActions from './flows'
import * as settingsActions from './settings'

export const INIT = 'MSG_QUEUE_INIT'
export const ENQUEUE = 'MSG_QUEUE_ENQUEUE'
export const CLEAR = 'MSG_QUEUE_CLEAR'
export const FETCH_ERROR = 'MSG_QUEUE_FETCH_ERROR'

const handlers = {
    [eventLogActions.MSG_TYPE] : eventLogActions,
    [flowsActions.MSG_TYPE]    : flowsActions,
    [settingsActions.MSG_TYPE] : settingsActions,
}

const defaultState = {}

export default function reduce(state = defaultState, action) {
    switch (action.type) {

        case INIT:
            return {
                ...state,
                [action.queue]: [],
            }

        case ENQUEUE:
            return {
                ...state,
                [action.queue]: [...state[action.queue], action.msg],
            }

        case CLEAR:
            return {
                ...state,
                [action.queue]: null,
            }

        default:
            return state
    }
}

/**
 * @public websocket
 */
export function handleWsMsg(msg) {
    return (dispatch, getState) => {
        const handler = handlers[msg.type]
        if (msg.cmd === websocketActions.CMD_RESET) {
            return dispatch(fetchData(handler.MSG_TYPE))
        }
        if (getState().msgQueue[handler.MSG_TYPE]) {
            return dispatch({ type: ENQUEUE, queue: handler.MSG_TYPE, msg })
        }
        return dispatch(handler.handleWsMsg(msg))
    }
}

/**
 * @public
 */
export function fetchData(type) {
    return dispatch => {
        const handler = handlers[type]

        dispatch(init(handler.MSG_TYPE))

        fetchApi(handler.DATA_URL)
            .then(res => res.json())
            .then(json => dispatch(receive(type, json)))
            .catch(error => dispatch(fetchError(type, error)))
    }
}

/**
 * @private
 */
export function receive(type, res) {
    return (dispatch, getState) => {
        const handler = handlers[type]
        const queue = getState().msgQueue[handler.MSG_TYPE] || []

        dispatch(clear(handler.MSG_TYPE))
        dispatch(handler.receiveData(res.data))
        for (const msg of queue) {
            dispatch(handler.handleWsMsg(msg))
        }
    }
}

/**
 * @private
 */
export function init(queue) {
    return { type: INIT, queue }
}

/**
 * @private
 */
export function clear(queue) {
    return { type: CLEAR, queue }
}

/**
 * @private
 */
export function fetchError(type, error) {
    return { type: FETCH_ERROR, type, error }
}