Merge pull request #42 from NebulousLabs/include-real-stats

include real stats from siastats.info
This commit is contained in:
David Vorick 2020-02-24 18:30:13 -05:00 committed by GitHub
commit 85994d4eb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 241 additions and 133 deletions

View File

@ -1,32 +1,31 @@
import React, { Component } from "react";
import React, { useState } from "react";
import PropTypes from "prop-types";
import CountUp from "react-countup";
import VisibilitySensor from "react-visibility-sensor";
import Fade from "react-reveal/Fade";
import useStats, { AVAILABLE_STATS } from "./useStats";
import "./HomeNetwork.scss";
import { CircleIcon, FAQ } from "../";
import { SmallOrb, LogoSolid, Deco6, Deco7, Deco8 } from "../../svg";
const stats = [
{ name: "TB Used", value: 664 },
{ name: "TB Capacity", value: 2315 },
{ name: "Hosts", value: 335 },
{ name: "Storage/TB", value: 91, cent: true },
{ name: "Bandwidth/TB", value: 18, cent: true }
const STATS_MAP = [
{ name: "TB Used", key: AVAILABLE_STATS.STORAGE_USED_TB },
{ name: "TB Capacity", key: AVAILABLE_STATS.NETWORK_CAPACITY_TB },
{ name: "Hosts", key: AVAILABLE_STATS.ONLINE_HOSTS_COUNT },
{ name: "Storage/TB", key: AVAILABLE_STATS.STORAGE_COST_USD, currency: true },
{ name: "Bandwidth/TB", key: AVAILABLE_STATS.BANDWIDTH_DOWN_COST_USD, currency: true }
];
export default class HomeNetwork extends Component {
state = {
visable: false
};
onChange = isVisible => {
if (isVisible && !this.state.visable) {
this.setState({ visable: true });
export default function HomeNetwork() {
const [visible, setVisible] = useState(false);
const stats = useStats();
const onChange = isVisible => {
if (isVisible && !visible) {
setVisible(true);
}
};
render() {
return (
<div className="home-network">
<header className="home-network-header">
@ -50,16 +49,14 @@ export default class HomeNetwork extends Component {
</header>
<Fade duration={700} distance="40px" bottom>
<VisibilitySensor onChange={this.onChange} partialVisibility offset={{ bottom: 100 }} scrollThrottle={50}>
<VisibilitySensor onChange={onChange} partialVisibility offset={{ bottom: 100 }} scrollThrottle={50}>
<React.Fragment>
<div className="home-network-stats">
{stats.map((stat, i) => (
{STATS_MAP.map((stat, i) => (
<React.Fragment key={i}>
<div key={i} className="home-network-stat">
<div className="inner">
<h3>
{this.state.visable ? <CountUp end={stat.value} duration={3.2} /> : 0}
{stat.cent && "¢"}
</h3>
{visible && <StatValue stat={stat} value={stats[stat.key]} />}
<span className="network-stat-name">{stat.name}</span>
</div>
</div>
@ -70,6 +67,13 @@ export default class HomeNetwork extends Component {
<Deco7 className="deco-7" />
<Deco8 className="deco-8" />
</div>
<div className="home-network-stats-provider">
stats provided by{" "}
<a href="https://siastats.info" target="_blank" rel="noopener noreferrer">
siastats.info
</a>
</div>
</React.Fragment>
</VisibilitySensor>
</Fade>
@ -79,10 +83,10 @@ export default class HomeNetwork extends Component {
<p>
<strong>Skynet Webportals</strong> are low cost servers that sit between Skynet and everyday users,
enabling them to access Skynet content without needing to operate any special software. As Skylinks are
generated, they can be shared with anyone to retrieve data from any Webportal. The original uploader
does not need to stay online in order for the file to remain available. The Sia network serves as the
backend storage layer for Skynet and handles all of the pinning, guaranteeing both high speeds and
excellent uptime.
generated, they can be shared with anyone to retrieve data from any Webportal. The original uploader does
not need to stay online in order for the file to remain available. The Sia network serves as the backend
storage layer for Skynet and handles all of the pinning, guaranteeing both high speeds and excellent
uptime.
</p>
</Fade>
@ -121,8 +125,8 @@ export default class HomeNetwork extends Component {
<Fade duration={700} distance="40px" bottom>
<FAQ title="How do I integrate Skynet into my app?">
<p>
Applications can be deployed in under a minute and be immediately available globally. Skynet includes
an API and SDKs which integrate seamlessly with existing applications.
Applications can be deployed in under a minute and be immediately available globally. Skynet includes an
API and SDKs which integrate seamlessly with existing applications.
<a
href="https://skynet.helpdocs.io/article/hrshqsn9wz-integrating-skynet"
target="_blank"
@ -170,5 +174,26 @@ export default class HomeNetwork extends Component {
</div>
</div>
);
}
}
function StatValue({ stat, value }) {
const displayDollars = stat.currency && value >= 1;
const displayCents = stat.currency && value < 1;
return (
<h3>
{displayDollars && "$"}
<CountUp end={displayCents ? value * 100 : value} duration={3.2} decimals={displayDollars ? 2 : 0} />
{displayCents && "¢"}
</h3>
);
}
StatValue.propTypes = {
stat: PropTypes.shape({
key: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
currency: PropTypes.bool
}).isRequired,
value: PropTypes.number.isRequired
};

View File

@ -65,6 +65,21 @@
}
}
.home-network-stats-provider {
text-align: right;
color: $green;
font-size: 13px;
margin-right: 12px; // keep the same as the border radius of .home-network-stats
a {
color: $green;
&:hover {
color: $black;
}
}
}
.deco-6 {
position: absolute;
top: -185px;

View File

@ -0,0 +1,68 @@
import { useEffect, useState } from "react";
export const AVAILABLE_STATS = {
ONLINE_HOSTS_COUNT: "onlineHostsCount",
STORAGE_USED_TB: "storageUsedTB",
NETWORK_CAPACITY_TB: "networkCapacityTB",
STORAGE_COST_USD: "storageCostUSD",
BANDWIDTH_DOWN_COST_USD: "bandwidthDownCostUSD"
};
export default function useStats() {
const [stats, setStats] = useState({
[AVAILABLE_STATS.ONLINE_HOSTS_COUNT]: null,
[AVAILABLE_STATS.STORAGE_USED_TB]: null,
[AVAILABLE_STATS.NETWORK_CAPACITY_TB]: null,
[AVAILABLE_STATS.STORAGE_COST_USD]: null,
[AVAILABLE_STATS.BANDWIDTH_DOWN_COST_USD]: null
});
useEffect(() => {
async function fetchData() {
const [bandwidth, storage, price] = await Promise.all([getBandwidthStats(), getStorageStats(), getPriceStats()]);
setStats({ ...bandwidth, ...storage, ...price });
}
fetchData();
}, [setStats]);
return stats;
}
async function getBandwidthStats() {
// { up: 76.09, down: 102.66, upusd: 0.23, downusd: 0.32 }
const response = await fetch("https://siastats.info/dbs/bandwidthpricesdb.json");
const data = await response.json();
const current = data[data.length - 1];
return {
[AVAILABLE_STATS.BANDWIDTH_DOWN_COST_USD]: current.downusd
};
}
async function getPriceStats() {
// { price: 504.59, newcontractformation: 30.79, usd: 1.55, sfperfees: 8.98 }
const response = await fetch("https://siastats.info/dbs/storagepricesdb.json");
const data = await response.json();
const current = data[data.length - 1];
return {
[AVAILABLE_STATS.STORAGE_COST_USD]: current.usd
};
}
async function getStorageStats() {
// { block_height: 247816, block_timestamp: 1582285828, hashrate: 6212581269715416,
// difficulty: 3501953420754597000, coin_supply: 43638591164, coin_price_USD: 0.003,
// market_cap_USD: 130915773, used_storage_TB: 725.26, network_capacity_TB: 2270.96,
// online_hosts: 360, active_contracts: 62997 }
const response = await fetch("https://siastats.info/dbs/network_status.json");
const data = await response.json();
return {
[AVAILABLE_STATS.ONLINE_HOSTS_COUNT]: data.online_hosts,
[AVAILABLE_STATS.STORAGE_USED_TB]: data.used_storage_TB,
[AVAILABLE_STATS.NETWORK_CAPACITY_TB]: data.network_capacity_TB
};
}