Skip to content
This repository has been archived by the owner on Jul 22, 2020. It is now read-only.

Commit

Permalink
feat: failed fetch data state and logic
Browse files Browse the repository at this point in the history
  • Loading branch information
manuel-calavera authored and sunnygleason committed Sep 13, 2019
1 parent 89e8671 commit ffbe973
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 14 deletions.
15 changes: 12 additions & 3 deletions src/AppV2.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import {CssBaseline, makeStyles} from '@material-ui/core';
import {MuiThemeProvider} from '@material-ui/core/styles';
import {observer} from 'mobx-react-lite';
import React, {lazy, Suspense} from 'react';
import {hot} from 'react-hot-loader/root';
import {Route, Switch} from 'react-router-dom';
import Header from 'v2/components/Header';
import Footer from 'v2/components/Footer';
import theme from 'v2/theme';
import socket from 'v2/stores/socket';
import FailedPanel from 'v2/components/UI/FailedPanel';
import Socket from 'v2/stores/socket';

try {
socket.init();
Socket.init();
} catch (err) {
console.error('Socket init failed:', err);
}
Expand All @@ -35,13 +37,16 @@ const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
overflow: 'hidden',
minHeight: '100vh',
},
content: {
marginLeft: 50,
minWidth: '1px',
padding: '50px 24px 0 24px',
maxWidth: 'calc(100% - 50px)',
width: '100%',
display: 'flex',
flexDirection: 'column',
[theme.breakpoints.down('sm')]: {
marginLeft: 0,
padding: 0,
Expand All @@ -66,13 +71,17 @@ const useStyles = makeStyles(theme => ({

const App = () => {
const classes = useStyles();
const {hasError} = Socket;

return (
<MuiThemeProvider theme={theme}>
<div className={classes.root}>
<CssBaseline />
<Header />

<div className={classes.content}>
<div className={classes.toolbar} />
{hasError && <FailedPanel />}
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Dashboard} />
Expand Down Expand Up @@ -104,4 +113,4 @@ const App = () => {
);
};

export default hot(App);
export default hot(observer(App));
5 changes: 4 additions & 1 deletion src/v2/api/socket.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import RobustWebSocket from 'robust-websocket';
import {CONNECTION_TIMEOUT} from 'v2/constants';

import * as EndpointConfig from '../../EndpointConfig';

export const initSocket = () => {
return new RobustWebSocket(EndpointConfig.getApiWebsocketUrl());
return new RobustWebSocket(EndpointConfig.getApiWebsocketUrl(), null, {
timeout: CONNECTION_TIMEOUT,
});
};
6 changes: 3 additions & 3 deletions src/v2/assets/icons/warn.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/v2/components/EndpointSelector/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import useStyles from './styles';

const EndpointSelector = () => {
const classes = useStyles();
const {endpointName, updateEndpointName} = socketActions;
const {endpointName, updateEndpointName, setError} = socketActions;
const handleEndpointChange = event => {
const endpointName = event.target.value;
EndpointConfig.setEndpointName(endpointName);
updateEndpointName(endpointName);
socketActions.init();
setError(false);
updateBaseUrl();
};
const endPointsList = EndpointConfig.getEndpoints();
Expand Down
28 changes: 28 additions & 0 deletions src/v2/components/UI/FailedPanel/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {Typography} from '@material-ui/core';
import React from 'react';
import {ReactComponent as WarnIcon} from 'v2/assets/icons/warn.svg';

import useStyles from './styles';

const FailedPanel = () => {
const classes = useStyles();
return (
<div className={classes.root}>
<div className={classes.body}>
<WarnIcon fill="#f71ef4" />
<Typography className={classes.text}>
Data currently unavailable. Report issues on{' '}
<a
href="https://github.com/solana-labs/networkexplorer/issues"
rel="noopener noreferrer"
target="_blank"
>
Github
</a>
</Typography>
</div>
</div>
);
};

export default FailedPanel;
26 changes: 26 additions & 0 deletions src/v2/components/UI/FailedPanel/styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {makeStyles} from '@material-ui/core';
import getColor from 'v2/utils/getColor';

export default makeStyles(theme => ({
root: {
paddingTop: 50,
marginBottom: 'auto',
},
body: {
backgroundColor: getColor('grey')(theme),
padding: 15,
textTransform: 'uppercase',
display: 'flex',
alignItems: 'center',
color: getColor('pink')(theme),
'& svg': {
marginRight: 15,
},
},
text: {
fontWeight: 'bold',
'& a': {
color: getColor('main')(theme),
},
},
}));
2 changes: 2 additions & 0 deletions src/v2/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ export const TDS_STAGES = [
duration: TDS_DEFAULT_STAGE_LENGTH_BLOCKS,
},
];

export const CONNECTION_TIMEOUT = 10000;
17 changes: 11 additions & 6 deletions src/v2/stores/nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,17 @@ class Store {
};

fetchClusterInfo = flow(function*() {
const res = yield API.getClusterInfo();
const data = res.data;
this.network = data.network;
this.totalStaked = data.totalStaked;
this.supply = data.supply;
this.networkInflationRate = data.networkInflationRate;
try {
const res = yield API.getClusterInfo();
const data = res.data;
this.network = data.network;
this.totalStaked = data.totalStaked;
this.supply = data.supply;
this.networkInflationRate = data.networkInflationRate;
return res;
} catch (e) {
throw e;
}
});

get mapMarkers() {
Expand Down
17 changes: 17 additions & 0 deletions src/v2/stores/socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import {observable, decorate, action} from 'mobx';
import {initSocket} from 'v2/api/socket';
import networkOverview from 'v2/stores/networkOverview';
import nodes from 'v2/stores/nodes';
import {CONNECTION_TIMEOUT} from 'v2/constants';

import * as EndpointConfig from '../../EndpointConfig';

const socketActions = {
isLoading: false,
hasError: false,
actions: {
'global-info': networkOverview.updateGlobalStats,
blk: networkOverview.addBlock,
Expand All @@ -15,6 +17,7 @@ const socketActions = {
},
endpointName: EndpointConfig.getEndpointName(),
onMessage(event) {
this.setError(false);
this.setLoading(false);
const {t, m} = JSON.parse(event.data);
this.actions[t](m);
Expand All @@ -27,20 +30,34 @@ const socketActions = {
}
this.ws = initSocket();
this.ws.onmessage = event => this.onMessage(event);
this.ws.onerror = () => {
this.setError(true);
};
setTimeout(() => {
if (this.ws.readyState === 0) {
this.setError(true);
}
}, CONNECTION_TIMEOUT);
},
updateEndpointName(endpointName) {
this.setLoading(false);
this.endpointName = endpointName;
},
setLoading(loading) {
this.isLoading = loading;
},
setError(hasError) {
this.hasError = hasError;
},
};

decorate(socketActions, {
endpointName: observable,
updateEndpointName: action.bound,
setLoading: action.bound,
setError: action.bound,
isLoading: observable,
hasError: observable,
});

export default socketActions;

0 comments on commit ffbe973

Please sign in to comment.