import React from 'react' import Table from 'react-bootstrap/Table' import Form from 'react-bootstrap/Form' import Button from 'react-bootstrap/Button' import scrollMonitor from 'scrollmonitor' import './App.css' import BreakPoint from './components/BreakPoint' import FlowPreview from './components/FlowPreview' import ViewFlow from './components/ViewFlow' import { FlowManager } from './flow' import { parseMessage, SendMessageType, buildMessageMeta, Flow, MessageType } from './message' interface IState { flows: Flow[] flow: Flow | null flowTab: 'Headers' | 'Preview' | 'Response' } class App extends React.Component { private flowMgr: FlowManager private ws: WebSocket | null private pageBottom: HTMLDivElement | null private autoScore = false constructor(props: any) { super(props) this.flowMgr = new FlowManager() this.state = { flows: this.flowMgr.showList(), flow: null, flowTab: 'Headers', // Headers, Preview, Response } this.ws = null this.pageBottom = null } componentDidMount() { this.initWs() } componentWillUnmount() { if (this.ws) { this.ws.close() } } initWs() { if (this.ws) return let host if (process.env.NODE_ENV === 'development') { host = 'localhost:9081' } else { host = new URL(document.URL).host } this.ws = new WebSocket(`ws://${host}/echo`) this.ws.binaryType = 'arraybuffer' this.ws.onopen = () => { console.log('OPEN') } this.ws.onclose = () => { console.log('CLOSE') } this.ws.onmessage = evt => { const msg = parseMessage(evt.data) if (!msg) { console.error('parse error:', evt.data) return } // console.log('msg:', msg) if (msg.type === MessageType.REQUEST) { const flow = new Flow(msg) this.flowMgr.add(flow) this.setState({ flows: this.flowMgr.showList() }, () => { if (this.pageBottom && this.autoScore) this.pageBottom.scrollIntoView({ behavior: 'auto' }) }) } else if (msg.type === MessageType.REQUEST_BODY) { const flow = this.flowMgr.get(msg.id) if (!flow) return flow.addRequestBody(msg) this.setState({ flows: this.state.flows }) } else if (msg.type === MessageType.RESPONSE) { const flow = this.flowMgr.get(msg.id) if (!flow) return flow.addResponse(msg) this.setState({ flows: this.state.flows }) } else if (msg.type === MessageType.RESPONSE_BODY) { const flow = this.flowMgr.get(msg.id) if (!flow || !flow.response) return flow.addResponseBody(msg) this.setState({ flows: this.state.flows }) } } this.ws.onerror = evt => { console.log('ERROR:', evt) } } initScrollMonitor() { if (!this.pageBottom) return const watcher = scrollMonitor.create(this.pageBottom) watcher.enterViewport(() => { this.autoScore = true }) watcher.exitViewport(() => { this.autoScore = false }) } render() { const { flows } = this.state return (
{ const value = e.target.value this.flowMgr.changeFilterLazy(value, () => { this.setState({ flows: this.flowMgr.showList() }) }) }} >
{ const msg = buildMessageMeta(SendMessageType.CHANGE_BREAK_POINT_RULES, rules) if (this.ws) this.ws.send(msg) }} />
{ flows.map(f => { const fp = f.preview() return ( { this.setState({ flow: f }) }} /> ) }) }
No Method Host Path Type Status Size Time
{ this.setState({ flow: null }) }} onReRenderFlows={() => { this.setState({ flows: this.state.flows }) }} onMessage={msg => { if (this.ws) this.ws.send(msg) }} />
{ if (this.pageBottom) return this.pageBottom = el this.initScrollMonitor() }} style={{ height: '0px', visibility: 'hidden' }}>bottom
) } } export default App