Rewritten to hooks

This commit is contained in:
2019-07-05 13:38:02 +02:00
parent a17faa9482
commit 41b4d3b115
12 changed files with 278 additions and 393 deletions

View File

@@ -18,7 +18,7 @@ import {
} from 'react-native-debug-console'; } from 'react-native-debug-console';
network.attach(); network.attach();
log.attach(true); log.attach();
context.hello = () => 'earth'; context.hello = () => 'earth';
console.log('fooo'); console.log('fooo');

View File

@@ -1,12 +1,10 @@
import React from 'react'; import React, { useState } from 'react';
import { import {
StyleSheet, StyleSheet,
View, View,
Text,
TextInput, TextInput,
} from 'react-native'; } from 'react-native';
import styled from 'styled-components/native'; import styled from 'styled-components/native';
import State from '../../data/State';
import { context } from '../../../console'; import { context } from '../../../console';
import log from '../../../log'; import log from '../../../log';
import Icon from '../../base/Icon'; import Icon from '../../base/Icon';
@@ -36,13 +34,11 @@ const styles = StyleSheet.create({
const Input = ({ const Input = ({
logs, logs,
}) => ( }) => {
<State> const [text, setText] = useState('');
{({ const [history, setHistory] = useState([]);
text = '', const [historyOffset, setHistoryOffset] = useState();
history = [], return (
historyOffset,
}, setState) => (
<View style={styles.container}> <View style={styles.container}>
<Button <Button
onPress={() => { onPress={() => {
@@ -50,10 +46,8 @@ const Input = ({
currentOffset += 1; currentOffset += 1;
const index = history.length - 1 - currentOffset; const index = history.length - 1 - currentOffset;
if (history[index]) { if (history[index]) {
setState({ setText(history[index]);
text: history[index], setHistoryOffset(currentOffset);
historyOffset: currentOffset,
});
} }
}} }}
> >
@@ -66,10 +60,8 @@ const Input = ({
currentOffset -= 1; currentOffset -= 1;
const index = history.length - 1 - currentOffset; const index = history.length - 1 - currentOffset;
if (history[index]) { if (history[index]) {
setState({ setText(history[index]);
text: history[index], setHistoryOffset(currentOffset);
historyOffset: currentOffset,
});
} }
}} }}
> >
@@ -82,7 +74,7 @@ const Input = ({
autoCorrect={false} autoCorrect={false}
style={styles.input} style={styles.input}
value={text} value={text}
onChangeText={text => setState({ text })} onChangeText={text => setText(text)}
/> />
<Button <Button
onPress={() => { onPress={() => {
@@ -92,11 +84,9 @@ const Input = ({
const fn = new Function(...contextKeys, text); const fn = new Function(...contextKeys, text);
try { try {
fn(...contextValues); fn(...contextValues);
setState({ setText('');
text: '', setHistoryOffset(undefined);
history: newHistory, setHistory(newHistory);
historyOffset: undefined,
});
} catch (err) { } catch (err) {
log.error([err]); log.error([err]);
} }
@@ -105,8 +95,7 @@ const Input = ({
<Icon name="play" /> <Icon name="play" />
</Button> </Button>
</View> </View>
)} );
</State> };
);
export default Input; export default Input;

View File

@@ -1,11 +1,10 @@
import React from 'react'; import React, { useState } from 'react';
import { import {
StyleSheet, StyleSheet,
View, View,
} from 'react-native'; } from 'react-native';
import log from '../../../log'; import log from '../../../log';
import Log from '../../data/Log'; import useLog from '../../data/log';
import State from '../../data/State';
import Toolbar, { import Toolbar, {
Button, Button,
Selector, Selector,
@@ -33,15 +32,10 @@ const initFilters = [
const Console = ({ const Console = ({
includeStackTrace, includeStackTrace,
}) => ( }) => {
<Log> const logs = useLog();
{({ logs }) => ( const [filters, setFilters] = useState(initFilters);
<State return (
initState={{
filters: initFilters,
}}
>
{({ filters }, setState) => (
<View style={styles.container}> <View style={styles.container}>
<Toolbar> <Toolbar>
<Selector <Selector
@@ -50,9 +44,7 @@ const Console = ({
options={filters} options={filters}
multiSelect multiSelect
onSelect={(selected) => { onSelect={(selected) => {
setState({ setFilters([...selected]);
filters: selected,
});
}} }}
/> />
<Seperator /> <Seperator />
@@ -65,10 +57,7 @@ const Console = ({
<Output filter={filters.filter(f => f.selected).map(f => f.name)} logs={logs} includeStackTrace={includeStackTrace} /> <Output filter={filters.filter(f => f.selected).map(f => f.name)} logs={logs} includeStackTrace={includeStackTrace} />
<Input /> <Input />
</View> </View>
)} );
</State> };
)}
</Log>
);
export default Console; export default Console;

View File

@@ -1,11 +1,10 @@
import React from 'react'; import React, { useState } from 'react';
import { import {
StyleSheet, StyleSheet,
View, View,
} from 'react-native'; } from 'react-native';
import network from '../../../network'; import network from '../../../network';
import State from '../../data/State'; import useRequests from '../../data/requests';
import Network from '../../data/Network';
import Toolbar, { import Toolbar, {
Button, Button,
Seperator, Seperator,
@@ -27,13 +26,9 @@ const styles = StyleSheet.create({
}, },
}); });
let i = 0; let i = 0;
const Console = () => ( const Console = () => {
<State> const requests = useRequests();
{({ const [active, setActive] = useState();
active,
}, setState) => (
<Network>
{({ requests }) => {
const selected = active >= 0 ? requests[active] : undefined; const selected = active >= 0 ? requests[active] : undefined;
return ( return (
<View style={styles.container}> <View style={styles.container}>
@@ -48,15 +43,11 @@ const Console = () => (
<List <List
selected={selected ? selected.id : undefined} selected={selected ? selected.id : undefined}
requests={requests} requests={requests}
onSelect={(i) => setState({ active: i })} onSelect={(i) => setActive(i)}
/> />
{selected && <Details {...selected} />} {selected && <Details {...selected} />}
</View> </View>
); );
}} }
</Network>
)}
</State>
);
export default Console; export default Console;

View File

@@ -1,7 +1,6 @@
import React from 'react'; import React, { useState } from 'react';
import styled from 'styled-components/native'; import styled from 'styled-components/native';
import Storage from '../../data/Storage'; import useStorage from '../../data/storage';
import State from '../../data/State';
import Toolbar, { import Toolbar, {
Button, Button,
Seperator, Seperator,
@@ -15,11 +14,15 @@ const Wrapper = styled.View`
const StorageView = ({ const StorageView = ({
provider, provider,
}) => ( }) => {
<State> const [selected, setSelected] = useState();
{({ selected }, setState) => ( const {
<Storage provider={provider}> data,
{(data, update, removeItem, clear) => ( update,
removeItem,
clear,
} = useStorage(provider);
return (
<Wrapper> <Wrapper>
<Toolbar> <Toolbar>
<Seperator /> <Seperator />
@@ -42,17 +45,16 @@ const StorageView = ({
</Toolbar> </Toolbar>
<Keys <Keys
selected={selected} selected={selected}
onSelect={(key) => setState({ selected: key })} onSelect={(key) => {
setSelected(key);
}}
keys={Object.keys(data)} keys={Object.keys(data)}
/> />
{selected && data[selected] && ( {selected && data[selected] && (
<Value value={data[selected]} /> <Value value={data[selected]} />
)} )}
</Wrapper> </Wrapper>
)} );
</Storage> };
)}
</State>
);
export default StorageView; export default StorageView;

View File

@@ -1,13 +1,11 @@
import React, { Fragment } from 'react'; import React, { Fragment, useState } from 'react';
import styled from 'styled-components/native'; import styled from 'styled-components/native';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { import {
Text, Text,
StyleSheet, StyleSheet,
TouchableOpacity,
View, View,
} from 'react-native'; } from 'react-native';
import State from '../data/State';
import Icon from '../base/Icon'; import Icon from '../base/Icon';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@@ -67,15 +65,10 @@ const Console = ({
tabs, tabs,
onClose, onClose,
onDownload, onDownload,
}) => ( }) => {
const [active, setActive] = useState(0);
return (
<View style={styles.container}> <View style={styles.container}>
<State
initState={{
active: 0,
}}
>
{({ active }, setState) => (
<Fragment>
<Header> <Header>
<TabScroll horizontal> <TabScroll horizontal>
<TabWrapper> <TabWrapper>
@@ -84,7 +77,7 @@ const Console = ({
key={name} key={name}
style={active === i ? styles.tabActive : styles.tabInactive} style={active === i ? styles.tabActive : styles.tabInactive}
onPress={() => { onPress={() => {
setState({ active: i }); setActive(i);
}} }}
> >
<Text>{name}</Text> <Text>{name}</Text>
@@ -108,11 +101,9 @@ const Console = ({
)} )}
</Header> </Header>
{tabs[active] && tabs[active].view} {tabs[active] && tabs[active].view}
</Fragment>
)}
</State>
</View> </View>
); );
};
Console.propTypes = { Console.propTypes = {
tabs: PropTypes.arrayOf(PropTypes.shape({ tabs: PropTypes.arrayOf(PropTypes.shape({

View File

@@ -1,9 +1,8 @@
import React, { Fragment } from 'react'; import React, { Fragment, useState } from 'react';
import { import {
SafeAreaView, SafeAreaView,
TouchableOpacity, TouchableOpacity,
} from 'react-native'; } from 'react-native';
import State from '../../data/State';
import Button from './Button'; import Button from './Button';
import Row from '../Row'; import Row from '../Row';
import Icon from '../Icon'; import Icon from '../Icon';
@@ -17,14 +16,14 @@ const Selector = ({
onSelect, onSelect,
options = [], options = [],
...others ...others
}) => ( }) => {
<State> const [open, setOpen] = useState(false);
{({ open }, setState) => ( return (
<Fragment> <Fragment>
<Button <Button
{...others} {...others}
onPress={() => { onPress={() => {
setState({ open: true }) setOpen(true);
}} }}
/> />
<Modal <Modal
@@ -32,7 +31,7 @@ const Selector = ({
transparent={false} transparent={false}
visible={!!open} visible={!!open}
onRequestClose={() => { onRequestClose={() => {
setState({ open: false }) setOpen(false);
}} }}
> >
<SafeAreaView <SafeAreaView
@@ -43,7 +42,7 @@ const Selector = ({
name="Close" name="Close"
icon="close" icon="close"
onPress={() => { onPress={() => {
setState({ open: false }) setOpen(false);
}} }}
/> />
{options.map((option) => ( {options.map((option) => (
@@ -69,8 +68,7 @@ const Selector = ({
</SafeAreaView> </SafeAreaView>
</Modal> </Modal>
</Fragment> </Fragment>
)} );
</State> };
);
export default Selector; export default Selector;

View File

@@ -1,38 +1,19 @@
import { Component } from 'react'; import { useEffect, useState } from 'react';
import log from '../../log'; import log from '../../log';
class Log extends Component { const useLog = () => {
constructor() { const [logs, setLogs] = useState([]);
super(); useEffect(() => {
this.state = { const update = (newLogs) => {
logs: [], setLogs([...newLogs]);
};
this.setLogs = this.setLogs.bind(this);
} }
log.listen(update);
componentDidMount() { return () => {
log.listen(this.setLogs); log.unlisten(update);
} }
}, []);
return logs;
};
componentWillUnmount() { export default useLog;
log.unlisten(this.setLogs);
}
setLogs(logs) {
this.setState({
logs,
});
}
render() {
const {
children,
} = this.props;
const component = children(
this.state,
);
return component;
}
}
export default Log;

View File

@@ -1,38 +0,0 @@
import { Component } from 'react';
import network from '../../network';
class Network extends Component {
constructor() {
super();
this.state = {
requests: [],
};
this.setRequests = this.setRequests.bind(this);
}
componentDidMount() {
network.listen(this.setRequests);
}
componentWillUnmount() {
network.unlisten(this.setRequests);
}
setRequests(requests) {
this.setState({
requests,
});
}
render() {
const {
children,
} = this.props;
const component = children(
this.state,
);
return component;
}
}
export default Network;

View File

@@ -1,20 +0,0 @@
import React, { Component } from 'react';
class State extends Component {
constructor(props, ...others) {
super(props, ...others);
this.state = props.initState || {};
this.setState = this.setState.bind(this);
}
render() {
const { children } = this.props;
const component = children(
this.state,
this.setState,
);
return component;
}
}
export default State;

View File

@@ -1,57 +1,40 @@
import { Component } from 'react'; import { useState, useEffect } from 'react';
class Storage extends Component { const useStorage = (provider) => {
constructor() { const [data, setData] = useState({});
super();
this.state = {
data: {},
};
this.update = this.update.bind(this);
this.removeItem = this.removeItem.bind(this);
this.clear = this.clear.bind(this);
}
componentDidMount() { const update = async () => {
this.update(); const keys = await provider.getAllKeys();
} const values = await Promise.all(keys.map(key => provider.getItem(key)));
async removeItem(name) {
await this.props.provider.removeItem(name);
await this.update();
}
async clear() {
await this.props.provider.clear();
await this.update();
}
async update() {
try {
const keys = await this.props.provider.getAllKeys();
const values = await Promise.all(keys.map(key => this.props.provider.getItem(key)));
const data = {}; const data = {};
for (let i = 0; i < keys.length; i++) { for (let i = 0; i < keys.length; i++) {
const key = keys[i]; const key = keys[i];
const value = values[i]; const value = values[i];
data[key] = value; data[key] = value;
} }
this.setState({ setData(data);
data, };
});
} catch (err) { const removeItem = async (name) => {
console.error(err); await provider.removeItem(name);
} await update();
} }
render() { const clear = async () => {
const { await provider.clear();
children, await update();
} = this.props; }
const {
useEffect(() => {
update().catch(err => console.error(err));
}, []);
return {
data, data,
} = this.state; update,
return children(data, this.update, this.removeItem, this.clear); removeItem,
clear,
} }
} }
export default Storage; export default useStorage;

View File

@@ -0,0 +1,19 @@
import { useState, useEffect } from 'react';
import network from '../../network';
const useRequests = () => {
const [requests, setRequests] = useState([]);
useEffect(() => {
const update = (newRequests) => {
setRequests(newRequests);
};
network.listen(update);
return () => {
network.unlisten(update);
};
}, []);
return requests;
};
export default useRequests;