diff --git a/components/NetworkStatus/index.js b/components/NetworkStatus/index.js new file mode 100644 index 00000000..33e19d53 --- /dev/null +++ b/components/NetworkStatus/index.js @@ -0,0 +1,44 @@ +// @flow +import * as React from 'react'; +import * as styles from './styles'; + +type Props = {}; +type State = { + online: boolean +}; + +class NetworkStatus extends React.Component { + state = { + online: true + }; + + componentDidMount() { + if (typeof window !== 'undefined') { + window.addEventListener('online', this.updateOnlineStatus); + window.addEventListener('offline', this.updateOnlineStatus); + } + } + + updateOnlineStatus = () => { + const condition = navigator.onLine ? 'online' : 'offline'; + if (condition === 'offline') { + this.setState({ online: false }); + } else if (condition === 'online') { + this.setState({ online: true }); + } + }; + + render() { + return ( +
+ {!this.state.online && ( + + Offline + + )} +
+ ); + } +} + +export default NetworkStatus; diff --git a/components/NetworkStatus/styles.js b/components/NetworkStatus/styles.js new file mode 100644 index 00000000..16ca5463 --- /dev/null +++ b/components/NetworkStatus/styles.js @@ -0,0 +1,17 @@ +import styled from 'styled-components'; + +const Root = styled.div` + position: fixed; + left: 30px; + bottom: 30px; +`; + +const Label = styled.div` + background: red; + color: #fff; + font-weight: bold; + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5); + padding: 10px; +`; + +export { Root, Label }; diff --git a/containers/Default.js b/containers/Default.js index deaeecc2..dacc8085 100644 --- a/containers/Default.js +++ b/containers/Default.js @@ -6,6 +6,7 @@ import PropTypes from 'prop-types'; import App from '../components/App'; import Header from '../components/Header'; import ProjectInfo from '../components/ProjectInfo'; +import NetworkStatus from '../components/NetworkStatus'; type Props = { title?: string, @@ -25,6 +26,7 @@ const Default = (props: Props) => (
{props.children} + ); diff --git a/libraries/withData.js b/libraries/withData.js index 247031f5..18fc39f4 100644 --- a/libraries/withData.js +++ b/libraries/withData.js @@ -41,7 +41,7 @@ export default ( }; static defaultProps = { - accessToken: null + accessToken: '' }; constructor(props: Props) { @@ -67,17 +67,24 @@ export default ( }; if (!process.browser) { - const client = apolloClient(headers || {}, token || '', {}); + const client = apolloClient(headers || {}, token || '', {}, ctx); const store = reduxStore(); - const app = ( - - - - - - ); - await getDataFromTree(app); + try { + const app = ( + + + + + + ); + await getDataFromTree(app); + } catch (error) { + // Prevent Apollo Client GraphQL errors from crashing SSR. + // Handle them in components via the data.error prop: + // https://github.com/apollographql/react-apollo/issues/406 + // http://dev.apollodata.com/react/api-queries.html#graphql-query-data-error + } apolloState = client.cache.extract(); serverState = store.getState();