Browse Source

feature(network map): loading screen for network map

renovate/lint-staged-8.x
Jack Mallers 7 years ago
parent
commit
a51b14f080
  1. 22
      app/components/Network/CanvasNetworkGraph.css
  2. 58
      app/components/Network/CanvasNetworkGraph.js
  3. 156
      app/components/Network/CanvasNetworkGraph.scss
  4. 18
      app/reducers/network.js
  5. 6
      app/routes/network/components/Network.js
  6. 11
      app/routes/network/containers/NetworkContainer.js

22
app/components/Network/CanvasNetworkGraph.css

@ -1,22 +0,0 @@
.network {
width: 100%;
height: 100vh;
animation: fadein 0.5s;
animation-timing-function:linear;
animation-fill-mode: forwards;
animation-iteration-count: 1;
}
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: black ;
stroke-width: 0px;
}
.active-peer {
fill: pink;
}

58
app/components/Network/CanvasNetworkGraph.js

@ -2,7 +2,7 @@ import { findDOMNode } from 'react-dom'
import React, { Component } from 'react' import React, { Component } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import * as d3 from 'd3' import * as d3 from 'd3'
// import './CanvasNetworkGraph.css' import styles from './CanvasNetworkGraph.scss'
function generateSimulationData(nodes, edges) { function generateSimulationData(nodes, edges) {
const resNodes = nodes.map(node => Object.assign(node, { id: node.pub_key })) const resNodes = nodes.map(node => Object.assign(node, { id: node.pub_key }))
@ -26,7 +26,9 @@ class CanvasNetworkGraph extends Component {
simulationData: { simulationData: {
nodes: [], nodes: [],
links: [] links: []
} },
svgLoaded: false
} }
this._startSimulation = this._startSimulation.bind(this) this._startSimulation = this._startSimulation.bind(this)
@ -35,10 +37,31 @@ class CanvasNetworkGraph extends Component {
this._restart = this._restart.bind(this) this._restart = this._restart.bind(this)
} }
componentWillReceiveProps(nextProps) {
const { network } = nextProps
const { simulationData: { nodes, links } } = this.state
const simulationDataEmpty = !nodes.length && !links.length
const networkDataLoaded = network.nodes.length || network.edges.length
// if the simulationData is empty and we have data
if (simulationDataEmpty && networkDataLoaded) {
this.setState({
simulationData: generateSimulationData(network.nodes, network.edges)
})
}
}
componentDidMount() { componentDidMount() {
// wait for the svg to me in the DOM before we start the simulation // wait for the svg to me in the DOM before we start the simulation
const svgInterval = setInterval(() => { const svgInterval = setInterval(() => {
if (document.getElementById('map')) { if (document.getElementById('mapContainer')) {
d3.select('#mapContainer')
.append('svg')
.attr('id', 'map')
.attr('width', 800)
.attr('height', 800)
this._startSimulation() this._startSimulation()
clearInterval(svgInterval) clearInterval(svgInterval)
@ -79,7 +102,6 @@ class CanvasNetworkGraph extends Component {
componentWillUnmount() { componentWillUnmount() {
d3.select('#map') d3.select('#map')
.selectAll('*')
.remove() .remove()
} }
@ -177,6 +199,10 @@ class CanvasNetworkGraph extends Component {
.force('link', d3.forceLink(links).id(d => d.pub_key).distance(500)) .force('link', d3.forceLink(links).id(d => d.pub_key).distance(500))
.force('collide', d3.forceCollide(300)) .force('collide', d3.forceCollide(300))
.on('tick', this._ticked) .on('tick', this._ticked)
.on('end', () => {
this.setState({ svgLoaded: true })
})
// zoom // zoom
const zoom_handler = d3.zoom().on('zoom', this._zoomActions) const zoom_handler = d3.zoom().on('zoom', this._zoomActions)
@ -235,18 +261,22 @@ class CanvasNetworkGraph extends Component {
} }
render() { render() {
const { simulationData } = this.state const { svgLoaded } = this.state
const {
network: { nodes, edges, selectedChannel, networkLoading },
selectedPeerPubkeys,
selectedChannelIds,
currentRouteChanIds,
identity_pubkey
} = this.props
return ( return (
<div id='mapContainer' style={{ display: 'inline' }}> <div className={styles.mapContainer} id='mapContainer'>
<svg width='800' height='800' id='map'></svg> {
!svgLoaded &&
<div className={styles.loadingContainer}>
<div className={styles.loadingWrap}>
<div className={styles.loader}></div>
<div className={styles.loaderbefore}></div>
<div className={styles.circular}></div>
<div className={`${styles.circular} ${styles.another}`}></div>
<div className={styles.text}>loading</div>
</div>
</div>
}
</div> </div>
) )
} }

156
app/components/Network/CanvasNetworkGraph.scss

@ -0,0 +1,156 @@
@import '../../variables.scss';
@keyframes fadein {
0% { background: $white; }
50% { background: lighten($secondary, 50%); }
100% { background: $secondary; animation-fill-mode:forwards; }
}
.mapContainer {
position: relative;
display: inline-block;
width: 70%;
height: 100%;
}
.loadingContainer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: $secondary;
}
.loadingWrap {
position: relative;
top: calc(50% - 150px);
width: 150px;
margin: 0 auto;
}
.loader {
position: absolute;
top: 0;
z-index: 10;
width: 50px;
height: 50px;
border: 15px solid;
border-radius: 50%;
border-top-color: rgba(44,44,44,0);
border-right-color: rgba(55,55,55,0);
border-bottom-color: rgba(66,66,66,0);
border-left-color: rgba(33,33,33,0);
animation: loadEr 3s infinite;
}
@keyframes loadEr {
0% {
border-top-color: rgba(44,44,44,0);
border-right-color: rgba(55,55,55,0);
border-bottom-color: rgba(66,66,66,0);
border-left-color: rgba(33,33,33,0);
}
10.4% {
border-top-color: rgba(44,44,44,0.5);
border-right-color: rgba(55,55,55,0);
border-bottom-color: rgba(66,66,66,0);
border-left-color: rgba(33,33,33,0);
}
20.8% {
border-top-color: rgba(44,44,44,0);
border-right-color: rgba(55,55,55,0);
border-bottom-color: rgba(66,66,66,0);
border-left-color: rgba(33,33,33,0);
}
31.2% {
border-top-color: rgba(44,44,44,0);
border-right-color: rgba(55,55,55,0.5);
border-bottom-color: rgba(66,66,66,0);
border-left-color: rgba(33,33,33,0);
}
41.6% {
border-top-color: rgba(44,44,44,0);
border-right-color: rgba(55,55,55,0);
border-bottom-color: rgba(66,66,66,0);
border-left-color: rgba(33,33,33,0);
transform: rotate(40deg);
}
52% {
border-top-color: rgba(44,44,44,0);
border-right-color: rgba(55,55,55,0);
border-bottom-color: rgba(66,66,66,0.5);
border-left-color: rgba(33,33,33,0);
}
62.4% {
border-top-color: rgba(44,44,44,0);
border-right-color: rgba(55,55,55,0);
border-bottom-color: rgba(66,66,66,0);
border-left-color: rgba(33,33,33,0);
}
72.8% {
border-top-color: rgba(44,44,44,0);
border-right-color: rgba(55,55,55,0);
border-bottom-color: rgba(66,66,66,0);
border-left-color: rgba(33,33,33,0.5);
}
}
.loaderbefore {
width: 50px;
height:50px;
border: 15px solid #ddd;
border-radius: 50%;
position: absolute;
top: 0;
z-index: 9;
}
.circular {
position: absolute;
top: -15px;
left: -15px;
width: 70px;
height: 70px;
border: 20px solid;
border-radius: 50%;
border-top-color: #333;
border-left-color: #fff;
border-bottom-color: #333;
border-right-color: #fff;
opacity: 0.2;
animation: poof 5s infinite;
}
@keyframes poof {
0% {transform: scale(1,1) rotate(0deg); opacity: 0.2;}
50% {transform: scale(4,4) rotate(360deg); opacity: 0;}
}
.another {
opacity: 0.1;
transform: rotate(90deg);
animation: poofity 5s infinite;
animation-delay: 1s;
}
@keyframes poofity {
0% {transform: scale(1,1) rotate(90deg); opacity: 0.1;}
50% {transform: scale(4,4) rotate(-360deg); opacity: 0;}
}
.text {
position: absolute;
top: 95px;
left: 8px;
font-family: Arial;
text-transform: uppercase;
color: #888;
animation: opaa 10s infinite;
}
@keyframes opaa {
0% {opacity: 1;}
10% {opacity: 0.5}
15% {opacity: 1;}
30% {opacity: 1;}
65% {opacity: 0.3;}
90% {opacity: 0.8;}
}

18
app/reducers/network.js

@ -23,8 +23,10 @@ export const UPDATE_PAY_REQ = 'UPDATE_PAY_REQ'
export const RESET_PAY_REQ = 'RESET_PAY_REQ' export const RESET_PAY_REQ = 'RESET_PAY_REQ'
export const UPDATE_SELECTED_PEERS = 'UPDATE_SELECTED_PEERS' export const UPDATE_SELECTED_PEERS = 'UPDATE_SELECTED_PEERS'
export const CLEAR_SELECTED_PEERS = 'CLEAR_SELECTED_PEERS'
export const UPDATE_SELECTED_CHANNELS = 'UPDATE_SELECTED_CHANNELS' export const UPDATE_SELECTED_CHANNELS = 'UPDATE_SELECTED_CHANNELS'
export const CLEAR_SELECTED_CHANNELS = 'CLEAR_SELECTED_CHANNELS'
export const GET_INFO_AND_QUERY_ROUTES = 'GET_INFO_AND_QUERY_ROUTES' export const GET_INFO_AND_QUERY_ROUTES = 'GET_INFO_AND_QUERY_ROUTES'
export const RECEIVE_INFO_AND_QUERY_ROUTES = 'RECEIVE_INFO_AND_QUERY_ROUTES' export const RECEIVE_INFO_AND_QUERY_ROUTES = 'RECEIVE_INFO_AND_QUERY_ROUTES'
@ -113,6 +115,18 @@ export function clearQueryRoutes() {
} }
} }
export function clearSelectedPeers() {
return {
type: CLEAR_SELECTED_PEERS
}
}
export function clearSelectedChannels() {
return {
type: CLEAR_SELECTED_CHANNELS
}
}
// Send IPC event for describeNetwork // Send IPC event for describeNetwork
export const fetchDescribeNetwork = () => (dispatch) => { export const fetchDescribeNetwork = () => (dispatch) => {
dispatch(getDescribeNetwork()) dispatch(getDescribeNetwork())
@ -185,6 +199,7 @@ const ACTION_HANDLERS = {
...state, selectedPeers ...state, selectedPeers
} }
}, },
[CLEAR_SELECTED_PEERS]: state => ({ ...state, selectedPeers: [] }),
[UPDATE_SELECTED_CHANNELS]: (state, { channel }) => { [UPDATE_SELECTED_CHANNELS]: (state, { channel }) => {
let selectedChannels let selectedChannels
@ -200,7 +215,8 @@ const ACTION_HANDLERS = {
return { return {
...state, selectedChannels ...state, selectedChannels
} }
} },
[CLEAR_SELECTED_CHANNELS]: state => ({ ...state, selectedChannels: [] }),
} }
// ------------------------------------ // ------------------------------------

6
app/routes/network/components/Network.js

@ -34,10 +34,12 @@ class Network extends Component {
} }
componentWillUnmount() { componentWillUnmount() {
const { clearQueryRoutes, resetPayReq } = this.props const { clearQueryRoutes, resetPayReq, clearSelectedChannels, clearSelectedPeers } = this.props
clearQueryRoutes() clearQueryRoutes()
resetPayReq() resetPayReq()
clearSelectedChannels()
clearSelectedPeers()
} }
render() { render() {

11
app/routes/network/containers/NetworkContainer.js

@ -5,8 +5,13 @@ import {
fetchDescribeNetwork, fetchDescribeNetwork,
setCurrentTab, setCurrentTab,
updateSelectedPeers, updateSelectedPeers,
clearSelectedPeers,
updateSelectedChannels, updateSelectedChannels,
clearSelectedChannels,
setCurrentRoute, setCurrentRoute,
updatePayReq, updatePayReq,
@ -25,7 +30,10 @@ import Network from '../components/Network'
const mapDispatchToProps = { const mapDispatchToProps = {
fetchDescribeNetwork, fetchDescribeNetwork,
setCurrentTab, setCurrentTab,
updateSelectedPeers, updateSelectedPeers,
clearSelectedPeers,
updatePayReq, updatePayReq,
fetchInvoiceAndQueryRoutes, fetchInvoiceAndQueryRoutes,
setCurrentRoute, setCurrentRoute,
@ -35,7 +43,8 @@ const mapDispatchToProps = {
fetchPeers, fetchPeers,
fetchChannels, fetchChannels,
updateSelectedChannels updateSelectedChannels,
clearSelectedChannels
} }
const mapStateToProps = state => ({ const mapStateToProps = state => ({

Loading…
Cancel
Save