diff --git a/client/react-native/common/components/App.js b/client/react-native/common/components/App.js index 6b127ff874..5dc33fc1f7 100644 --- a/client/react-native/common/components/App.js +++ b/client/react-native/common/components/App.js @@ -1,5 +1,5 @@ import { I18nextProvider } from 'react-i18next' -import { Linking, Platform } from 'react-native' +import { Linking, Platform, View } from 'react-native' import { SafeAreaView } from 'react-navigation' import Config from 'react-native-config' import FlashMessage from 'react-native-flash-message' @@ -8,9 +8,9 @@ import React, { PureComponent } from 'react' import ReactNativeLanguages from 'react-native-languages' import { BASE_WEBSITE_URL, colors } from './../constants' -import { Flex, Animation } from './Library' import { contact, conversation } from '../utils' import { parse as parseUrl } from '../helpers/url' +import { Flex, Animation, MovableView, DebugStateBar } from './Library' import Accounts from './Screens/Accounts' import Instabug from '../helpers/Instabug' import i18n from '../i18n' @@ -149,10 +149,18 @@ export default class App extends PureComponent { deepLink, setDeepLink: deepLink => this.setDeepLink(deepLink), clearDeepLink: () => this.clearDeepLink(), + onRelayContextCreated: context => this.setState({ + debugBar: , + }), }} /> ) : null} + + + {this.state.debugBar} + + {Platform.OS === 'ios' && } diff --git a/client/react-native/common/components/Library/DebugStateBar.js b/client/react-native/common/components/Library/DebugStateBar.js new file mode 100644 index 0000000000..b9ce1c26e4 --- /dev/null +++ b/client/react-native/common/components/Library/DebugStateBar.js @@ -0,0 +1,257 @@ +import React, { PureComponent } from 'react' +import { colors } from '../../constants' +import { promiseWithTimeout } from 'react-relay-network-modern/es/middlewares/retry' +import { Flex, Text } from './index' +import { View } from 'react-native' +import RelayContext from '../../relay/RelayContext' +import Icon from './Icon' +import NavigationService from '../../helpers/NavigationService' + +const daemonStateValues = { + 'down': 0, + 'connecting': 1, + 'connected': 2, +} + +class DebugStateBar extends PureComponent { + constructor (props) { + super(props) + this.state = { + watchTime: 10000, + listenAddrs: [], + listenInterfaceAddrs: [], + timeouted: false, + requestTimeout: 3000, + listenAddrTimer: null, + InterfaceAddrTimer: null, + bertyColor: colors.lightGrey, + bleColor: colors.lightGrey, + bgBertyColor: colors.inputGrey, + bgBleColor: colors.inputGrey, + bleText: 'off', + bleState: false, + bertyText: 'no daemon', + + daemonState: daemonStateValues.down, + peers: [], + compact: true, + } + } + + componentDidMount () { + this.fetchListenAddrs() + this.fetchListenInterfaceAddrs() + + this.fetchPeers() + this.subscriber = this.props.context.subscriptions.monitorPeers.subscribe( + { + iterator: undefined, + updater: (store, data) => { + const peer = data.MonitorPeers + this.addPeer(peer) + }, + } + ) + } + + componentWillUnmount () { + const { listenAddrTimer, InterfaceAddrTimer } = this.state + + if (listenAddrTimer !== null) { + clearTimeout(listenAddrTimer) + } + + if (InterfaceAddrTimer !== null) { + clearTimeout(InterfaceAddrTimer) + } + + this.subscriber.unsubscribe() + } + + timeoutPromise = () => { + return new Promise((resolve, reject) => { + this.setState({ timeouted: true }, this.setColor) + reject(new Error('Request timed out')) + }) + } + + addPeer = (peer) => { + this.setState(prevState => ({ + peers: [...prevState.peers.filter(p => p.id !== peer.id), peer], + })) + } + + fetchPeers = () => { + this.props.context.queries.Peers.fetch().then(data => + this.setState({ peers: data.list }) + ) + } + + fetchListenAddrs = () => { + const { context } = this.props + const { watchTime, requestTimeout, timeouted } = this.state + + promiseWithTimeout(context.queries.GetListenAddrs.fetch(), requestTimeout, this.timeoutPromise).then(e => { + const timer = setTimeout(this.fetchListenAddrs, watchTime) + + // if we previously timeouted we need to refetch peers + if (timeouted === true) { + this.fetchPeers() + } + + this.setState({ + listenAddrs: e.addrs, + timeouted: false, + listenAddrTimer: timer, + }, this.setColor) + }).catch(err => { + const timer = setTimeout(this.fetchListenAddrs, watchTime) + this.setState({ + listenAddrTimer: timer, + peers: [], + timeouted: true, + listenAddrs: [], + }) + console.log('err listen address', err) + }) + } + + fetchListenInterfaceAddrs = () => { + const { context } = this.props + const { watchTime, requestTimeout, timeouted } = this.state + + promiseWithTimeout(context.queries.GetListenInterfaceAddrs.fetch(), requestTimeout, this.timeoutPromise).then(e => { + const timer = setTimeout(this.fetchListenInterfaceAddrs, watchTime) + + // if we previously timeouted we need to refetch peers + if (timeouted === true) { + this.fetchPeers() + } + + this.setState({ + listenInterfaceAddrs: e.addrs, + timeouted: false, + InterfaceAddrTimer: timer, + }, this.setColor) + }).catch(err => { + const timer = setTimeout(this.fetchListenInterfaceAddrs, watchTime) + this.setState({ + InterfaceAddrTimer: timer, + peers: [], + timeouted: true, + listenInterfaceAddrs: [], + }, this.setColor) + console.log('err Listen address', err) + }) + } + + setColor = () => { + const { listenAddrs, listenInterfaceAddrs, timeouted } = this.state + let bertyColor = colors.orange + let bgBertyColor = colors.orange25 + let bertyText = 'connecting' + let daemonState = daemonStateValues.connecting + let bleColor = colors.lightGrey + let bgBleColor = colors.inputGrey + let bleText = 'off' + let bleState = false + + if (listenAddrs.length > 0 && listenInterfaceAddrs.length > 0) { + listenInterfaceAddrs.forEach((v, i, arr) => { + try { + const splited = v.split('/') + if (splited[1] === 'ip4' && splited[2] !== '127.0.0.1') { + bertyColor = colors.green + bgBertyColor = colors.green25 + bertyText = 'connected' + daemonState = daemonStateValues.connected + } + if (splited[1] === 'ble' && splited[2] !== '00000000-0000-0000-0000-000000000000') { + bleColor = colors.green + bgBleColor = colors.green25 + bleText = 'on' + bleState = true + } + } catch (e) { + // Silence error since /p2p-circuit isn't valid + // console.log(e) + } + }) + } + + if (timeouted) { + bertyColor = colors.pink + bgBertyColor = colors.pink25 + bertyText = 'no daemon' + daemonState = daemonStateValues.down + } + this.setState({ + bertyColor, + bgBertyColor, + bertyText, + bleText, + bleState, + bleColor, + bgBleColor, + daemonState, + }) + } + + getPeersColor = (peers) => { + if (peers.length > 0) { + return { + bgPeerColor: colors.blue25, + peerColor: colors.blue, + } + } + return { + bgPeerColor: colors.inputGrey, + peerColor: colors.lightGrey, + } + } + + render () { + const { bertyColor, bleColor, bleText, bertyText, peers, bgBertyColor, bgBleColor } = this.state + const { bgPeerColor, peerColor } = this.getPeersColor(peers) + const count = peers.reduce((acc, cur) => cur.connection === 1 ? acc + 1 : acc, 0) + + return ( + + + + + + { + this.state.compact ? : bertyText.toLocaleUpperCase() + } + + + NavigationService.navigate('network/peers')}>{count.toString()} + + + NavigationService.navigate('network/config')}>{bleText.toLocaleUpperCase()} + + + NavigationService.navigate('settings/devtools')} /> + + + ) + } +} + +const WrappedDebugStateBar = ({ context, ...props }) => { + if (context !== null) { + return + } + + return + {context => } + +} + +export default WrappedDebugStateBar diff --git a/client/react-native/common/components/Library/Header.js b/client/react-native/common/components/Library/Header.js index 11439cbac0..9419662465 100644 --- a/client/react-native/common/components/Library/Header.js +++ b/client/react-native/common/components/Library/Header.js @@ -4,8 +4,6 @@ import { Button, Flex, Text, SearchBar } from '.' import { colors } from '../../constants' import { padding, borderBottom, paddingBottom } from '../../styles' import { isRTL } from '../../i18n' -import RelayContext from '../../relay/RelayContext' -import { promiseWithTimeout } from 'react-relay-network-modern/es/middlewares/retry' const [defaultTextColor, defaultBackColor] = [colors.black, colors.white] @@ -13,188 +11,6 @@ const HeaderButton = ({ icon, color, style, ...otherProps }) => { return