diff options
Adds network loading retry / error screen.
Diffstat (limited to 'ui/app/components/loading-network-screen')
3 files changed, 188 insertions, 0 deletions
diff --git a/ui/app/components/loading-network-screen/index.js b/ui/app/components/loading-network-screen/index.js new file mode 100644 index 000000000..9d0612f26 --- /dev/null +++ b/ui/app/components/loading-network-screen/index.js @@ -0,0 +1,2 @@ +const LoadingNetworksScreen = require('./loading-network-screen.container') +module.exports = LoadingNetworksScreen diff --git a/ui/app/components/loading-network-screen/loading-network-screen.component.js b/ui/app/components/loading-network-screen/loading-network-screen.component.js new file mode 100644 index 000000000..98abf6bd2 --- /dev/null +++ b/ui/app/components/loading-network-screen/loading-network-screen.component.js @@ -0,0 +1,145 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Spinner from '../spinner' +import Button from '../button' + +class LoadingNetworkScreen extends Component { + constructor (props) { + super(props) + + this.state = { + showErrorScreen: false, + } + } + + static contextTypes = { + t: PropTypes.func, + } + + componentWillMount = () => { + this.cancelCallTimeout = setTimeout(this.cancelCall, this.props.cancelTime || 3000) + } + + getConnectingLabel = function (loadingMessage) { + if (loadingMessage) { + return loadingMessage + } + const { provider, providerId } = this.props + const providerName = provider.type + + let name + + if (providerName === 'mainnet') { + name = this.context.t('connectingToMainnet') + } else if (providerName === 'ropsten') { + name = this.context.t('connectingToRopsten') + } else if (providerName === 'kovan') { + name = this.context.t('connectingToKovan') + } else if (providerName === 'rinkeby') { + name = this.context.t('connectingToRinkeby') + } else { + name = this.context.t('connectingTo', [providerId]) + } + + return name + } + + renderMessage = () => { + return <span>{ this.getConnectingLabel(this.props.loadingMessage) }</span> + } + + renderLoadingScreenContent = () => { + return <div className="loading-overlay__screen-content"> + <Spinner color="#F7C06C" /> + {this.renderMessage()} + </div> + } + + renderErrorScreenContent = () => { + const { showNetworkDropdown, setProviderArgs, setProviderType } = this.props + + return <div className="loading-overlay__error-screen"> + <span className="loading-overlay__emoji">😞</span> + <span>Oops! Something went wrong.</span> + <div className="loading-overlay__error-buttons"> + <Button + type="default" + onClick={() => { + window.clearTimeout(this.cancelCallTimeout) + showNetworkDropdown() + }} + > + { 'Switch Networks' } + </Button> + + <Button + type="primary" + onClick={() => { + this.setState({ showErrorScreen: false }) + setProviderType(...setProviderArgs) + window.clearTimeout(this.cancelCallTimeout) + this.cancelCallTimeout = setTimeout(this.cancelCall, this.props.cancelTime || 3000) + }} + > + { 'Try Again' } + </Button> + </div> + </div> + } + + cancelCall = () => { + const { isLoadingNetwork } = this.props + + if (isLoadingNetwork) { + this.setState({ showErrorScreen: true }) + } + } + + componentDidUpdate = (prevProps) => { + const { provider } = this.props + const { provider: prevProvider } = prevProps + if (provider.type !== prevProvider.type) { + window.clearTimeout(this.cancelCallTimeout) + this.setState({ showErrorScreen: false }) + this.cancelCallTimeout = setTimeout(this.cancelCall, this.props.cancelTime || 3000) + } + } + + componentWillUnmount = () => { + window.clearTimeout(this.cancelCallTimeout) + } + + render () { + const { lastSelectedProvider, setProviderType } = this.props + + return ( + <div className="loading-overlay"> + <div + className="page-container__header-close" + onClick={() => setProviderType(lastSelectedProvider || 'ropsten')} + /> + <div className="loading-overlay__container"> + { this.state.showErrorScreen + ? this.renderErrorScreenContent() + : this.renderLoadingScreenContent() + } + </div> + </div> + ) + } +} + +LoadingNetworkScreen.propTypes = { + loadingMessage: PropTypes.string, + cancelTime: PropTypes.number, + provider: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), + providerId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + showNetworkDropdown: PropTypes.func, + setProviderArgs: PropTypes.array, + lastSelectedProvider: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), + setProviderType: PropTypes.func, + isLoadingNetwork: PropTypes.bool, + +} + +module.exports = LoadingNetworkScreen diff --git a/ui/app/components/loading-network-screen/loading-network-screen.container.js b/ui/app/components/loading-network-screen/loading-network-screen.container.js new file mode 100644 index 000000000..d0623e574 --- /dev/null +++ b/ui/app/components/loading-network-screen/loading-network-screen.container.js @@ -0,0 +1,41 @@ +import { connect } from 'react-redux' +import LoadingNetworkScreen from './loading-network-screen.component' +import actions from '../../actions' +import { getNetworkIdentifier } from '../../selectors' + +const mapStateToProps = state => { + const { + loadingMessage, + currentView, + } = state.appState + const { + provider, + lastSelectedProvider, + network, + } = state.metamask + const { rpcTarget, chainId, ticker, nickname, type } = provider + + const setProviderArgs = type === 'rpc' + ? [rpcTarget, chainId, ticker, nickname] + : [provider.type] + + return { + isLoadingNetwork: network === 'loading' && currentView.name !== 'config', + loadingMessage, + lastSelectedProvider, + setProviderArgs, + provider, + providerId: getNetworkIdentifier(state), + } +} + +const mapDispatchToProps = dispatch => { + return { + setProviderType: (type) => { + dispatch(actions.setProviderType(type)) + }, + showNetworkDropdown: () => dispatch(actions.showNetworkDropdown()), + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(LoadingNetworkScreen) |