This commit is contained in:
2018-08-22 23:44:26 +02:00
parent 7e635595f3
commit c8f41d45ea
24 changed files with 352 additions and 163 deletions

View File

@@ -7,6 +7,7 @@ import {
} from 'react-native';
import styled from 'styled-components/native';
import State from '../../data/State';
import { context } from '../../../console';
import log from '../../../log';
import Icon from '../../base/Icon';
@@ -86,8 +87,8 @@ const Input = ({
<Button
onPress={() => {
const newHistory = [...history, text];
const contextKeys = Object.keys(log.context);
const contextValues = Object.values(log.context);
const contextKeys = Object.keys(context);
const contextValues = Object.values(context);
const fn = new Function(...contextKeys, text);
try {
fn(...contextValues);

View File

@@ -101,6 +101,7 @@ const OutputList = ({
const Console = ({
logs,
includeStackTrace,
filter = [],
}) => (
<ScrollView
ref={ref => this.scrollView = ref}
@@ -109,7 +110,7 @@ const Console = ({
}}
>
<Wrapper>
{logs.map((log, i) => (
{logs.filter(l => filter.includes(l.type)).map((log, i) => (
<Row key={i}>
<Emphasis color={getColor(log.type)}>
{log.type}

View File

@@ -1,13 +1,16 @@
import React from 'react';
import {
StyleSheet,
Clipboard,
Alert,
View,
} from 'react-native';
import log from '../../../log';
import Log from '../../data/Log';
import Toolbar from '../../base/Toolbar';
import State from '../../data/State';
import Toolbar, {
Button,
Selector,
Seperator,
} from '../../base/Toolbar';
import Output from './Output';
import Input from './Input';
@@ -17,31 +20,53 @@ const styles = StyleSheet.create({
},
});
const initFilters = [
'error',
'warn',
'info',
'debug',
].map(i => ({
name: i,
value: i,
selected: true,
}))
const Console = ({
includeStackTrace,
}) => (
<Log>
{({ logs }) => (
<View style={styles.container}>
<Toolbar
items={[{
name: 'Download',
icon: 'download',
onPress: () => {
Clipboard.setString(JSON.stringify(logs, null, ' '));
Alert.alert(
'Copied to clipboard',
);
},
}, {
name: 'Clear',
icon: 'trash',
onPress: () => log.clear(),
}]}
/>
<Output logs={logs} includeStackTrace={includeStackTrace} />
<Input />
</View>
<State
initState={{
filters: initFilters,
}}
>
{({ filters }, setState) => (
<View style={styles.container}>
<Toolbar>
<Selector
name="Filter"
icon="filter"
options={filters}
multiSelect
onSelect={(selected) => {
setState({
filters: selected,
});
}}
/>
<Seperator />
<Button
name="Clear"
icon="trash"
onPress={() => log.clear()}
/>
</Toolbar>
<Output filter={filters.filter(f => f.selected).map(f => f.name)} logs={logs} includeStackTrace={includeStackTrace} />
<Input />
</View>
)}
</State>
)}
</Log>
);

View File

@@ -14,7 +14,6 @@ import CellHeader from '../../base/CellHeader';
import Tab from '../Tab';
const WebView = styled.WebView`
background: red;
`;
const theme = {
@@ -42,11 +41,10 @@ const Indented = styled.View`
margin: 0 25px;
`;
const getResponse = (request) => {
const getResponse = (contentType, request) => {
if (request.responseType == 'blob' || request.responseType == 'ArrayBuffer') {
return <Emphasis>🤖 Binary</Emphasis>
}
const contentType = request.getResponseHeader('content-type') || '';
const contentTypes = contentType.split(';').map(c => c.trim());
if (contentTypes.includes('application/json')) {
@@ -57,12 +55,13 @@ const getResponse = (request) => {
return <Fixed selectable={true}>{request.responseText}</Fixed>;
}
let i = 0;
const Data = ({
url,
method,
status,
headers,
request,
requestHeaders,
args = [],
}) => {
const headerInfo = Object.keys(headers).map(key => `${key}: ${headers[key]}`).join('\n');
@@ -73,7 +72,7 @@ const Data = ({
<Cell left="Method" right={method} />
<Cell left="Url" right={url} />
<CellHeader>Response Headers</CellHeader>
<Indented><Fixed>{request.getAllResponseHeaders()}</Fixed></Indented>
<Indented><Fixed>{requestHeaders}</Fixed></Indented>
{headerInfo && (
<Fragment>
<CellHeader>Request Headers</CellHeader>
@@ -92,21 +91,21 @@ const Data = ({
};
const Response = ({
contentType,
request,
}) => (
<ScrollView>
<View>
{getResponse(request)}
{getResponse(contentType, request)}
</View>
</ScrollView>
);
const getPreview = (request, url) => {
const getPreview = (contentType, request, url) => {
if (request.responseType == 'blob' || request.responseType == 'ArrayBuffer') {
return [];
}
const contentType = request.getResponseHeader('content-type') || '';
const contentTypes = contentType.split(';').map(c => c.trim());
if (contentTypes.includes('text/html')) {
@@ -134,7 +133,7 @@ const RequestDetails = (props) => (
}, {
name: 'Response',
view: <Response {...props} />
}, ...getPreview(props.request, props.url)]}
}, ...getPreview(props.contentType, props.request, props.url)]}
/>
);

View File

@@ -2,15 +2,14 @@ import React from 'react';
import {
StyleSheet,
View,
Clipboard,
Alert,
Text,
TouchableOpacity,
} from 'react-native';
import network from '../../../network';
import State from '../../data/State';
import Network from '../../data/Network';
import Toolbar from '../../base/Toolbar';
import Toolbar, {
Button,
Seperator,
} from '../../base/Toolbar';
import Details from './Details';
import List from './List';
@@ -27,7 +26,7 @@ const styles = StyleSheet.create({
flex: 1,
},
});
let i = 0;
const Console = () => (
<State>
{({
@@ -38,22 +37,14 @@ const Console = () => (
const selected = active >= 0 ? requests[active] : undefined;
return (
<View style={styles.container}>
<Toolbar
items={[{
name: 'Download',
icon: 'download',
onPress: () => {
Clipboard.setString(JSON.stringify(requests, null, ' '));
Alert.alert(
'Copied to clipboard',
);
},
}, {
name: 'Clear',
icon: 'trash',
onPress: () => network.clear(),
}]}
/>
<Toolbar>
<Seperator />
<Button
name="Clear"
icon="trash"
onPress={() => network.clear()}
/>
</Toolbar>
<List
selected={selected ? selected.id : undefined}
requests={requests}

View File

@@ -24,7 +24,7 @@ const Keys = ({
<Wrapper>
{keys.map(key => (
<Button
key={key}
key={key || '[unknown]'}
onPress={() => onSelect(key)}
>
<Row

View File

@@ -1,12 +1,11 @@
import React from 'react';
import styled from 'styled-components/native';
import {
Clipboard,
Alert,
} from 'react-native';
import Storage from '../../data/Storage';
import State from '../../data/State';
import Toolbar from '../../base/Toolbar';
import Toolbar, {
Button,
Seperator,
} from '../../base/Toolbar';
import Keys from './Keys';
import Value from './Value';
@@ -20,31 +19,25 @@ const StorageView = () => (
<Storage>
{(data, update, removeItem, clear) => (
<Wrapper>
<Toolbar
items={[{
name: 'Download',
icon: 'download',
onPress: () => {
Clipboard.setString(JSON.stringify(data, null, ' '));
Alert.alert(
'Copied to clipboard',
);
},
}, {
name: 'Refresh',
icon: 'reload',
onPress: update,
}, {
name: 'Clear',
icon: 'trash',
onPress: clear,
}, {
name: 'Delete',
icon: 'remove',
disabled: !selected,
onPress: () => removeItem(selected),
}]}
/>
<Toolbar>
<Seperator />
<Button
name="Refresh"
icon="reload"
onPress={update}
/>
<Button
name="Clear"
icon="trash"
onPress={clear}
/>
<Button
name="Delete"
icon="remove"
disabled={!selected}
onPress={() => removeItem(selected)}
/>
</Toolbar>
<Keys
selected={selected}
onSelect={(key) => setState({ selected: key })}

View File

@@ -45,6 +45,7 @@ const Console = ({
tabs,
buttons = [],
onClose,
onDownload,
}) => (
<View style={styles.container}>
<State
@@ -66,7 +67,13 @@ const Console = ({
<Text>{name}</Text>
</TouchableOpacity>
))}
{onDownload && (
<Button
onPress={onDownload}
>
<Icon name="download" />
</Button>
)}
{onClose && (
<Button
onPress={onClose}

View File

@@ -2,11 +2,15 @@ import React from 'react';
import {
StyleSheet,
View,
Alert,
Clipboard,
} from 'react-native';
import Tab from './Tab';
import Console from './Console';
import Requests from './Requests';
import Storage from './Storage';
import log from '../../log';
import network from '../../network';
const styles = StyleSheet.create({
container: {
@@ -18,22 +22,65 @@ const DevTool = ({
style,
includeStackTrace,
onClose,
}) => (
<View style={style || styles.container}>
<Tab
tabs={[{
name: 'Console',
view: <Console includeStackTrace={includeStackTrace} />,
}, {
name: 'Network',
view: <Requests />,
}, {
name: 'Storage',
view: <Storage />,
}]}
onClose={onClose}
/>
</View>
);
showNetwork = true,
showStorage = true,
showConsole = true,
additionTools = [],
}) => {
const views = [];
if (showConsole) {
views.push({
name: 'Console',
view: <Console includeStackTrace={includeStackTrace} />,
getData: log.get,
});
}
if (showNetwork) {
views.push({
name: 'Network',
view: <Requests />,
getData: network.get,
});
}
if (showStorage) {
views.push({
name: 'Storage',
view: <Storage />,
});
}
additionTools.forEach(tool => {
views.push(tool);
});
const getData = async () => {
const result = {};
for (let i = 0; i < views.length; i++) {
const view = views[i];
if (view.getData) {
result[view.name] = await view.getData();
}
};
Clipboard.setString(JSON.stringify(result, null, ' '));
Alert.alert(
'Copied to clipboard',
);
}
return (
<View style={style || styles.container}>
<Tab
tabs={views}
onClose={onClose}
onDownload={getData}
/>
</View>
);
};
export default DevTool;