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,65 +1,62 @@
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">
<Fade duration={700} distance="40px" bottom>
<div className="home-network-divider">
<CircleIcon>
<LogoSolid />
</CircleIcon>
<SmallOrb />
<div className="divider"></div>
<div className="small-divider"></div>
</div>
</Fade>
<Fade duration={700} distance="40px" bottom>
<h2>
Sia
<br />
<strong>Network</strong>
</h2>
</Fade>
</header>
return (
<div className="home-network">
<header className="home-network-header">
<Fade duration={700} distance="40px" bottom>
<VisibilitySensor onChange={this.onChange} partialVisibility offset={{ bottom: 100 }} scrollThrottle={50}>
<div className="home-network-divider">
<CircleIcon>
<LogoSolid />
</CircleIcon>
<SmallOrb />
<div className="divider"></div>
<div className="small-divider"></div>
</div>
</Fade>
<Fade duration={700} distance="40px" bottom>
<h2>
Sia
<br />
<strong>Network</strong>
</h2>
</Fade>
</header>
<Fade duration={700} distance="40px" bottom>
<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,105 +67,133 @@ export default class HomeNetwork extends Component {
<Deco7 className="deco-7" />
<Deco8 className="deco-8" />
</div>
</VisibilitySensor>
</Fade>
<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>
<div className="home-network-columns">
<div className="home-network-column left">
<Fade duration={700} distance="40px" bottom>
<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.
</p>
</Fade>
<div className="home-network-columns">
<div className="home-network-column left">
<Fade duration={700} distance="40px" bottom>
<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.
</p>
</Fade>
<Fade duration={700} distance="40px" bottom>
<p>
<strong>Sia</strong> is the leading decentralized cloud storage platform. No signups, no servers, no
trusted third parties. Sia leverages blockchain technology to create a data storage marketplace that is
more robust and more affordable than traditional cloud storage providers.
</p>
<Fade duration={700} distance="40px" bottom>
<p>
<strong>Sia</strong> is the leading decentralized cloud storage platform. No signups, no servers, no
trusted third parties. Sia leverages blockchain technology to create a data storage marketplace that is
more robust and more affordable than traditional cloud storage providers.
</p>
<p>
<a className="more" href="https://sia.tech/" target="_blank" rel="noopener noreferrer">
Learn more about Sia
</a>
</p>
</Fade>
</div>
<div className="home-network-column">
<Fade duration={700} distance="40px" bottom>
<FAQ title="How do I use Skynet?">
<p>
<a className="more" href="https://sia.tech/" target="_blank" rel="noopener noreferrer">
Learn more about Sia
Anyone can access files that have been uploaded to Skynet as long as they possess the corresponding
Skylinks. You can use any Webportal to download files!
<a
href="https://skynet.helpdocs.io/article/3p9z5g9s0e-skynet-how-to"
target="_blank"
rel="noopener noreferrer"
className="more read-more"
>
read more
</a>
</p>
</Fade>
</div>
<div className="home-network-column">
<Fade duration={700} distance="40px" bottom>
<FAQ title="How do I use Skynet?">
<p>
Anyone can access files that have been uploaded to Skynet as long as they possess the corresponding
Skylinks. You can use any Webportal to download files!
<a
href="https://skynet.helpdocs.io/article/3p9z5g9s0e-skynet-how-to"
target="_blank"
rel="noopener noreferrer"
className="more read-more"
>
read more
</a>
</p>
</FAQ>
</Fade>
</FAQ>
</Fade>
<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.
<a
href="https://skynet.helpdocs.io/article/hrshqsn9wz-integrating-skynet"
target="_blank"
rel="noopener noreferrer"
className="more read-more"
>
read more
</a>
</p>
</FAQ>
</Fade>
<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.
<a
href="https://skynet.helpdocs.io/article/hrshqsn9wz-integrating-skynet"
target="_blank"
rel="noopener noreferrer"
className="more read-more"
>
read more
</a>
</p>
</FAQ>
</Fade>
<Fade duration={700} distance="40px" bottom>
<FAQ title="How fast is Skynet?">
<p>
Skynet's speeds rival centralized providers and surpass all decentralized offerings. A typical Skynet
download starts in under 500 ms and can stream at rates as high as 1 Gbps!
<a
href="https://skynet.helpdocs.io/article/430teoxgqc-skynet-speed"
target="_blank"
rel="noopener noreferrer"
className="more read-more"
>
read more
</a>
</p>
</FAQ>
</Fade>
<Fade duration={700} distance="40px" bottom>
<FAQ title="How fast is Skynet?">
<p>
Skynet's speeds rival centralized providers and surpass all decentralized offerings. A typical Skynet
download starts in under 500 ms and can stream at rates as high as 1 Gbps!
<a
href="https://skynet.helpdocs.io/article/430teoxgqc-skynet-speed"
target="_blank"
rel="noopener noreferrer"
className="more read-more"
>
read more
</a>
</p>
</FAQ>
</Fade>
<Fade duration={700} distance="40px" bottom>
<FAQ title="How much does it cost to run a Webportal?">
<p>
Storage costs 10x lower than centralized providers and bandwidth costs are 100x lower without
sacrificing performance or reliability.
</p>
</FAQ>
</Fade>
<Fade duration={700} distance="40px" bottom>
<FAQ title="How much does it cost to run a Webportal?">
<p>
Storage costs 10x lower than centralized providers and bandwidth costs are 100x lower without
sacrificing performance or reliability.
</p>
</FAQ>
</Fade>
<Fade duration={700} distance="40px" bottom>
<a className="more more-faq" href="https://support.siasky.net" target="_blank" rel="noopener noreferrer">
View more FAQ
</a>
</Fade>
</div>
<Fade duration={700} distance="40px" bottom>
<a className="more more-faq" href="https://support.siasky.net" target="_blank" rel="noopener noreferrer">
View more FAQ
</a>
</Fade>
</div>
</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
};
}