From f2cdf5afe3b59473ead438e1e51f4443b1822285 Mon Sep 17 00:00:00 2001 From: Alan Foster Date: Fri, 18 Aug 2017 11:37:12 +0100 Subject: [PATCH 1/2] Network Inspector - convert list view to flat list --- Libraries/Inspector/NetworkOverlay.js | 429 ++++++++++++-------------- 1 file changed, 200 insertions(+), 229 deletions(-) diff --git a/Libraries/Inspector/NetworkOverlay.js b/Libraries/Inspector/NetworkOverlay.js index db0216a0059e82..83a9bbe180b4b2 100644 --- a/Libraries/Inspector/NetworkOverlay.js +++ b/Libraries/Inspector/NetworkOverlay.js @@ -11,7 +11,7 @@ */ 'use strict'; -const ListView = require('ListView'); +const FlatList = require('FlatList'); const React = require('React'); const ScrollView = require('ScrollView'); const StyleSheet = require('StyleSheet'); @@ -22,12 +22,12 @@ const WebSocketInterceptor = require('WebSocketInterceptor'); const XHRInterceptor = require('XHRInterceptor'); const LISTVIEW_CELL_HEIGHT = 15; -const SEPARATOR_THICKNESS = 2; // Global id for the intercepted XMLHttpRequest objects. let nextXHRId = 0; type NetworkRequestInfo = { + id: number, type?: string, url?: string, method?: string, @@ -51,49 +51,31 @@ type NetworkRequestInfo = { * Show all the intercepted network requests over the InspectorPanel. */ class NetworkOverlay extends React.Component }> { - _requests: Array; - _listViewDataSource: ListView.DataSource; - _listView: ?ListView; - _listViewHighlighted: bool; - _listViewHeight: number; - _scrollView: ?ScrollView; - _detailViewItems: Array>>; - _listViewOnLayout: (event: Event) => void; - _captureRequestListView: (listRef: ?ListView) => void; - _captureDetailScrollView: (scrollRef: ?ScrollView) => void; - _renderRow: ( - rowData: NetworkRequestInfo, - sectionID: number, - rowID: number, - highlightRow: (sectionID: number, rowID: number) => void, + _requestsListView: ?FlatList; + _detailScrollView: ?ScrollView; + _captureRequestsListView: (listRef: ?FlatList) => void; + _renderItemDetail: ( + index: number ) => React.Element; _closeButtonClicked: () => void; - // Map of `socketId` -> `index in `_requests``. + // Map of `socketId` -> `index in `this.state.requests`. _socketIdMap: Object; - // Map of `xhr._index` -> `index in `_requests``. + // Map of `xhr._index` -> `index in `this.state.requests`. _xhrIdMap: {[key: number]: number}; constructor(props: Object) { super(props); - this._requests = []; - this._detailViewItems = []; - this._listViewDataSource = - new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); this.state = { - dataSource: this._listViewDataSource.cloneWithRows([]), - newDetailInfo: false, - detailRowID: null, + detailRowId: null, + requests: [] }; - this._listViewHighlighted = false; - this._listViewHeight = 0; - this._captureRequestListView = this._captureRequestListView.bind(this); + this._captureRequestsListView = this._captureRequestsListView.bind(this); this._captureDetailScrollView = this._captureDetailScrollView.bind(this); - this._listViewOnLayout = this._listViewOnLayout.bind(this); - this._renderRow = this._renderRow.bind(this); + this._renderItem = this._renderItem.bind(this); + this._renderItemDetail = this._renderItemDetail.bind(this); this._closeButtonClicked = this._closeButtonClicked.bind(this); this._socketIdMap = {}; this._xhrIdMap = {}; @@ -109,21 +91,18 @@ class NetworkOverlay extends React.Component { @@ -131,12 +110,16 @@ class NetworkOverlay extends React.Component { @@ -144,8 +127,12 @@ class NetworkOverlay extends React.Component { - const xhrIndex = this._getRequestIndexByXHRID(xhr._index); - if (xhrIndex === -1) { - return; - } - const networkInfo = this._requests[xhrIndex]; - networkInfo.status = status; - networkInfo.timeout = timeout; - networkInfo.response = response; - networkInfo.responseURL = responseURL; - networkInfo.responseType = responseType; - this._genDetailViewItem(xhrIndex); + const xhrIndex = this._getRequestIndexByXHRID(xhr._index); + if (xhrIndex === -1) { + return; } - ); + + this.setState(function ({ requests }) { + const networkRequestInfo = requests[xhrIndex]; + networkRequestInfo.status = status; + networkRequestInfo.timeout = timeout; + networkRequestInfo.response = response; + networkRequestInfo.responseURL = responseURL; + networkRequestInfo.responseType = responseType; + + return { requests }; + }); + }); // Fire above callbacks. XHRInterceptor.enableInterception(); @@ -195,20 +189,18 @@ class NetworkOverlay extends React.Component { - const socketIndex = this._requests.length; + const socketIndex = this.state.requests.length; this._socketIdMap[socketId] = socketIndex; const _webSocket: NetworkRequestInfo = { + id: socketIndex, 'type': 'WebSocket', 'url': url, 'protocols': protocols, }; - this._requests.push(_webSocket); - this._detailViewItems.push([]); - this._genDetailViewItem(socketIndex); - this.setState( - {dataSource: this._listViewDataSource.cloneWithRows(this._requests)}, - this._scrollToBottom(), - ); + + this.setState({ + requests: this.state.requests.concat(_webSocket) + }, this._scrollRequestsToBottom); } ); @@ -219,10 +211,14 @@ class NetworkOverlay extends React.Component { @@ -244,12 +246,18 @@ class NetworkOverlay extends React.Component { @@ -257,8 +265,13 @@ class NetworkOverlay extends React.Component { @@ -266,8 +279,13 @@ class NetworkOverlay extends React.Component void, - ): React.Element { - let urlCellViewStyle = styles.urlEvenCellView; - let methodCellViewStyle = styles.methodEvenCellView; - if (rowID % 2 === 1) { - urlCellViewStyle = styles.urlOddCellView; - methodCellViewStyle = styles.methodOddCellView; - } + _renderItem({ item, index }) { + const tableRowViewStyle = [ + styles.tableRow, + (index % 2 === 1 ? styles.tableRowOdd : styles.tableRowEven), + index === this.state.detailRowId && styles.tableRowPressed + ]; + const urlCellViewStyle = styles.urlCellView; + const methodCellViewStyle = styles.methodCellView; + return ( { - this._pressRow(rowID); - highlightRow(sectionID, rowID); + this._pressRow(index); }}> - - + - {rowData.url} + {item.url} - {this._getTypeShortName(rowData.type)} + {this._getTypeShortName(item.type)} - ); } - _renderSeperator( - sectionID: number, - rowID: number, - adjacentRowHighlighted: bool): React.Element { + _renderItemDetail(id) { + const requestItem = this.state.requests[id]; + const details = Object.keys(requestItem).map((key) => { + if (key === 'id') { + return; + } + + return ( + + + {key} + + + {this._getStringByValue(requestItem[key])} + + + ); + }); + return ( - + + + + v + + + + + {details} + + ); } - _scrollToBottom(): void { - if (this._listView) { - const scrollResponder = this._listView.getScrollResponder(); - if (scrollResponder) { - const scrollY = Math.max( - this._requests.length * LISTVIEW_CELL_HEIGHT + - (this._listViewHighlighted ? 2 * SEPARATOR_THICKNESS : 0) - - this._listViewHeight, - 0, - ); - scrollResponder.scrollResponderScrollTo({ - x: 0, - y: scrollY, - animated: true - }); - } + _scrollRequestsToBottom(): void { + if (this._requestsListView) { + this._requestsListView.scrollToEnd(); } } - _captureRequestListView(listRef: ?ListView): void { - this._listView = listRef; - } - - _listViewOnLayout(event: any): void { - const {height} = event.nativeEvent.layout; - this._listViewHeight = height; + _captureRequestsListView(listRef: ?FlatList): void { + this._requestsListView = listRef; } /** * Popup a scrollView to dynamically show detailed information of * the request, when pressing a row in the network flow listView. */ - _pressRow(rowID: number): void { - this._listViewHighlighted = true; + _pressRow(rowId: number): void { this.setState( - {detailRowID: rowID}, - this._scrollToTop(), + { + detailRowId: rowId + }, + this._scrollDetailToTop, ); } - _scrollToTop(): void { - if (this._scrollView) { - this._scrollView.scrollTo({ + _scrollDetailToTop(): void { + if (this._detailScrollView) { + this._detailScrollView.scrollTo({ y: 0, animated: false, }); @@ -384,11 +402,11 @@ class NetworkOverlay extends React.Component - - {key} - - - {this._getStringByValue(requestItem[key])} - - - ); - } - // Re-render if this network request is showing in the detail view. - if (this.state.detailRowID != null && - Number(this.state.detailRowID) === index) { - this.setState({newDetailInfo: true}); - } + _keyExtractor(request: NetworkRequestInfo): string { + return String(request.id); } render() { + const { requests, detailRowId } = this.state; + return ( - {this.state.detailRowID != null && - - - v - - } - {this.state.detailRowID != null && - - {this._detailViewItems[this.state.detailRowID]} - } + {detailRowId != null && this._renderItemDetail(detailRowId)} + - {this._requests.length > 0 && + {requests.length > 0 && URL @@ -484,14 +467,13 @@ class NetworkOverlay extends React.Component } - ); @@ -515,6 +497,16 @@ const styles = StyleSheet.create({ tableRow: { flexDirection: 'row', flex: 1, + height: LISTVIEW_CELL_HEIGHT + }, + tableRowEven: { + backgroundColor: '#555', + }, + tableRowOdd: { + backgroundColor: '#000', + }, + tableRowPressed: { + backgroundColor: '#3B5998' }, cellText: { color: 'white', @@ -543,41 +535,20 @@ const styles = StyleSheet.create({ flex: 5, paddingLeft: 3, }, - methodOddCellView: { - height: 15, - borderColor: '#DCD7CD', - borderRightWidth: 1, - alignItems: 'center', - justifyContent: 'center', - backgroundColor: '#000', - flex: 1, - }, - urlOddCellView: { - height: 15, - borderColor: '#DCD7CD', - borderLeftWidth: 1, - borderRightWidth: 1, - justifyContent: 'center', - backgroundColor: '#000', - flex: 5, - paddingLeft: 3, - }, - methodEvenCellView: { + methodCellView: { height: 15, borderColor: '#DCD7CD', borderRightWidth: 1, alignItems: 'center', justifyContent: 'center', - backgroundColor: '#888', flex: 1, }, - urlEvenCellView: { + urlCellView: { height: 15, borderColor: '#DCD7CD', borderLeftWidth: 1, borderRightWidth: 1, justifyContent: 'center', - backgroundColor: '#888', flex: 5, paddingLeft: 3, }, @@ -601,7 +572,7 @@ const styles = StyleSheet.create({ color: 'white', fontSize: 11, }, - clostButtonText: { + closeButtonText: { color: 'white', fontSize: 10, }, From 88af3e94b5c9e754d471046c7a89c1ad0411279d Mon Sep 17 00:00:00 2001 From: Alan Foster Date: Sat, 19 Aug 2017 01:02:31 +0100 Subject: [PATCH 2/2] Network Inspector - Smarter scrolling to bottom --- Libraries/Inspector/NetworkOverlay.js | 79 +++++++++++++++++++-------- 1 file changed, 55 insertions(+), 24 deletions(-) diff --git a/Libraries/Inspector/NetworkOverlay.js b/Libraries/Inspector/NetworkOverlay.js index 83a9bbe180b4b2..efca7a9b859d90 100644 --- a/Libraries/Inspector/NetworkOverlay.js +++ b/Libraries/Inspector/NetworkOverlay.js @@ -55,8 +55,16 @@ class NetworkOverlay extends React.Component }> { _requestsListView: ?FlatList; + _requestsListViewScrollMetrics: { + offset: number, + visibleLength: number, + contentLength: number + }; _detailScrollView: ?ScrollView; _captureRequestsListView: (listRef: ?FlatList) => void; + _captureDetailScrollView: (scrollRef: ?ScrollView) => void; + _requestsListViewOnScroll: (Object) => void; + _renderItem: ({ item: NetworkRequestInfo, index: number }) => React.Element; _renderItemDetail: ( index: number ) => React.Element; @@ -74,6 +82,12 @@ class NetworkOverlay extends React.Component { @@ -154,13 +168,13 @@ class NetworkOverlay extends React.Component { + status, + timeout, + response, + responseURL, + responseType, + xhr, + ) => { const xhrIndex = this._getRequestIndexByXHRID(xhr._index); if (xhrIndex === -1) { return; @@ -200,7 +214,7 @@ class NetworkOverlay extends React.Component { - this._pressRow(index); - }}> - - - - {item.url} - - - - - {this._getTypeShortName(item.type)} - - + this._pressRow(index); + }}> + + + + {item.url} + + + + {this._getTypeShortName(item.type)} + + + ); } @@ -369,9 +383,19 @@ class NetworkOverlay extends React.Component