Merge pull request #5 from NebulousLabs/robbys-edits
- faster animations - fix mobile shapes - new copy button
This commit is contained in:
commit
1311539fee
|
@ -1,24 +1,24 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import Fade from 'react-reveal/Fade'
|
import Fade from "react-reveal/Fade";
|
||||||
import Reveal from 'react-reveal/Reveal'
|
import Reveal from "react-reveal/Reveal";
|
||||||
|
|
||||||
import { Arrow, FooterOrb, FooterCube, Built } from '../../svg'
|
import { Arrow, FooterOrb, FooterCube, Built } from "../../svg";
|
||||||
import './Footer.scss'
|
import "./Footer.scss";
|
||||||
import { Mailing } from '..'
|
import { Mailing } from "..";
|
||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
return (
|
return (
|
||||||
<Reveal effect="active">
|
<Reveal effect="active">
|
||||||
<footer className="footer">
|
<footer className="footer">
|
||||||
<div className="width">
|
<div className="width">
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<div className="footer-column">
|
<div className="footer-column">
|
||||||
<Built />
|
<Built />
|
||||||
</div>
|
</div>
|
||||||
</Fade>
|
</Fade>
|
||||||
|
|
||||||
<div className="footer-column">
|
<div className="footer-column">
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<h2>Sia Elsewhere</h2>
|
<h2>Sia Elsewhere</h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -48,7 +48,7 @@ export default function Footer() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="footer-column">
|
<div className="footer-column">
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<h2>Social</h2>
|
<h2>Social</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
|
@ -77,7 +77,7 @@ export default function Footer() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="footer-column">
|
<div className="footer-column">
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<h2>Stay up-to-date with Skynet updates</h2>
|
<h2>Stay up-to-date with Skynet updates</h2>
|
||||||
<Mailing id="check2" light />
|
<Mailing id="check2" light />
|
||||||
</Fade>
|
</Fade>
|
||||||
|
@ -88,5 +88,5 @@ export default function Footer() {
|
||||||
<FooterOrb className="footer-orb fadeInUp delay2" />
|
<FooterOrb className="footer-orb fadeInUp delay2" />
|
||||||
</footer>
|
</footer>
|
||||||
</Reveal>
|
</Reveal>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import Fade from 'react-reveal/Fade'
|
import Fade from "react-reveal/Fade";
|
||||||
|
|
||||||
import './HomeBuilt.scss'
|
import "./HomeBuilt.scss";
|
||||||
import { CircleIcon, CodeExamples } from '../'
|
import { CircleIcon, CodeExamples } from "../";
|
||||||
import { Cylinder, SmallOrb } from '../../svg'
|
import { Cylinder, SmallOrb } from "../../svg";
|
||||||
|
|
||||||
export default function HomeBuilt() {
|
export default function HomeBuilt() {
|
||||||
return (
|
return (
|
||||||
<div className="home-built">
|
<div className="home-built">
|
||||||
<header className="home-built-header">
|
<header className="home-built-header">
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<div className="home-built-divider">
|
<div className="home-built-divider">
|
||||||
<div className="small-divider" />
|
<div className="small-divider" />
|
||||||
<div className="divider" />
|
<div className="divider" />
|
||||||
|
@ -22,7 +22,7 @@ export default function HomeBuilt() {
|
||||||
<div className="small-divider" />
|
<div className="small-divider" />
|
||||||
</div>
|
</div>
|
||||||
</Fade>
|
</Fade>
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<h2>
|
<h2>
|
||||||
Infrastructure built for
|
Infrastructure built for
|
||||||
<br />
|
<br />
|
||||||
|
@ -31,9 +31,9 @@ export default function HomeBuilt() {
|
||||||
</Fade>
|
</Fade>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<CodeExamples />
|
<CodeExamples />
|
||||||
</Fade>
|
</Fade>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from "react";
|
||||||
import CountUp from 'react-countup'
|
import CountUp from "react-countup";
|
||||||
import VisibilitySensor from 'react-visibility-sensor'
|
import VisibilitySensor from "react-visibility-sensor";
|
||||||
import Fade from 'react-reveal/Fade'
|
import Fade from "react-reveal/Fade";
|
||||||
|
|
||||||
import './HomeNetwork.scss'
|
import "./HomeNetwork.scss";
|
||||||
import { CircleIcon, FAQ } from '../'
|
import { CircleIcon, FAQ } from "../";
|
||||||
import { SmallOrb, LogoSolid, Arrow, Deco6, Deco7, Deco8 } from '../../svg'
|
import { SmallOrb, LogoSolid, Arrow, Deco6, Deco7, Deco8 } from "../../svg";
|
||||||
|
|
||||||
const stats = [
|
const stats = [
|
||||||
{ name: 'TB Used', value: 664 },
|
{ name: "TB Used", value: 664 },
|
||||||
{ name: 'TB Capacity', value: 2315 },
|
{ name: "TB Capacity", value: 2315 },
|
||||||
{ name: 'Hosts', value: 335 },
|
{ name: "Hosts", value: 335 },
|
||||||
{ name: 'Storage/TB', value: 91, cent: true },
|
{ name: "Storage/TB", value: 91, cent: true },
|
||||||
{ name: 'Bandwidth/TB', value: 18, cent: true },
|
{ name: "Bandwidth/TB", value: 18, cent: true }
|
||||||
]
|
];
|
||||||
|
|
||||||
export default class HomeNetwork extends Component {
|
export default class HomeNetwork extends Component {
|
||||||
state = {
|
state = {
|
||||||
visable: false,
|
visable: false
|
||||||
}
|
};
|
||||||
|
|
||||||
onChange = isVisible => {
|
onChange = isVisible => {
|
||||||
if (isVisible && !this.state.visable) {
|
if (isVisible && !this.state.visable) {
|
||||||
this.setState({ visable: true })
|
this.setState({ visable: true });
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="home-network">
|
<div className="home-network">
|
||||||
<header className="home-network-header">
|
<header className="home-network-header">
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<div className="home-network-divider">
|
<div className="home-network-divider">
|
||||||
<CircleIcon>
|
<CircleIcon>
|
||||||
<LogoSolid />
|
<LogoSolid />
|
||||||
|
@ -40,7 +40,7 @@ export default class HomeNetwork extends Component {
|
||||||
<div className="small-divider"></div>
|
<div className="small-divider"></div>
|
||||||
</div>
|
</div>
|
||||||
</Fade>
|
</Fade>
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<h2>
|
<h2>
|
||||||
Sia
|
Sia
|
||||||
<br />
|
<br />
|
||||||
|
@ -49,16 +49,25 @@ export default class HomeNetwork extends Component {
|
||||||
</Fade>
|
</Fade>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<VisibilitySensor onChange={this.onChange} partialVisibility offset={{ bottom: 100 }} scrollThrottle={50}>
|
<VisibilitySensor
|
||||||
|
onChange={this.onChange}
|
||||||
|
partialVisibility
|
||||||
|
offset={{ bottom: 100 }}
|
||||||
|
scrollThrottle={50}
|
||||||
|
>
|
||||||
<div className="home-network-stats">
|
<div className="home-network-stats">
|
||||||
{stats.map((stat, i) => (
|
{stats.map((stat, i) => (
|
||||||
<React.Fragment key={i}>
|
<React.Fragment key={i}>
|
||||||
<div key={i} className="home-network-stat">
|
<div key={i} className="home-network-stat">
|
||||||
<div className="inner">
|
<div className="inner">
|
||||||
<h3>
|
<h3>
|
||||||
{this.state.visable ? <CountUp end={stat.value} duration={3.2} /> : 0}
|
{this.state.visable ? (
|
||||||
{stat.cent && '¢'}
|
<CountUp end={stat.value} duration={3.2} />
|
||||||
|
) : (
|
||||||
|
0
|
||||||
|
)}
|
||||||
|
{stat.cent && "¢"}
|
||||||
</h3>
|
</h3>
|
||||||
<span className="network-stat-name">{stat.name}</span>
|
<span className="network-stat-name">{stat.name}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -75,25 +84,31 @@ export default class HomeNetwork extends Component {
|
||||||
|
|
||||||
<div className="home-network-columns">
|
<div className="home-network-columns">
|
||||||
<div className="home-network-column left">
|
<div className="home-network-column left">
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<p>
|
<p>
|
||||||
Skynet Webportal is a low cost server that sits between Skynet and everyday users, enabling them to
|
Skynet Webportal is a low cost server that sits between Skynet
|
||||||
access Skynet content without needing to operate any special software. Once the Skylinks are generated,
|
and everyday users, enabling them to access Skynet content
|
||||||
they can be shared with anyone to fetch data from Skynet. The original uploader does not need to stay
|
without needing to operate any special software. Once the
|
||||||
online in order for the file to remain available. The Sia network handles all of the pinning,
|
Skylinks are generated, they can be shared with anyone to fetch
|
||||||
guaranteeing both high speeds and excellent uptime. A typical Skynet download starts in under 500
|
data from Skynet. The original uploader does not need to stay
|
||||||
milliseconds and can stream at rates as high as 1 gigabit per second. The Sia network serves as the
|
online in order for the file to remain available. The Sia
|
||||||
backend storage layer for Skynet.
|
network handles all of the pinning, guaranteeing both high
|
||||||
|
speeds and excellent uptime. A typical Skynet download starts in
|
||||||
|
under 500 milliseconds and can stream at rates as high as 1
|
||||||
|
gigabit per second. The Sia network serves as the backend
|
||||||
|
storage layer for Skynet.
|
||||||
</p>
|
</p>
|
||||||
</Fade>
|
</Fade>
|
||||||
|
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<p>
|
<p>
|
||||||
Sia is the leading decentralized cloud storage platform. No signups, no servers, no trusted third
|
Sia is the leading decentralized cloud storage platform. No
|
||||||
parties. Sia leverages blockchain technology to create a data storage marketplace that is more robust
|
signups, no servers, no trusted third parties. Sia leverages
|
||||||
and more affordable than traditional cloud storage providers. Storage costs are as much as 10x lower
|
blockchain technology to create a data storage marketplace that
|
||||||
than traditional infrastructure, bandwidth costs as much as 100x lower, all without sacrificing
|
is more robust and more affordable than traditional cloud
|
||||||
performance or reliability.
|
storage providers. Storage costs are as much as 10x lower than
|
||||||
|
traditional infrastructure, bandwidth costs as much as 100x
|
||||||
|
lower, all without sacrificing performance or reliability.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -104,41 +119,45 @@ export default class HomeNetwork extends Component {
|
||||||
</Fade>
|
</Fade>
|
||||||
</div>
|
</div>
|
||||||
<div className="home-network-column">
|
<div className="home-network-column">
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<FAQ title="What does pinning mean?">
|
<FAQ title="What does pinning mean?">
|
||||||
<p>
|
<p>
|
||||||
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer
|
Lorem Ipsum has been the industry's standard dummy text ever
|
||||||
took a galley of type and scrambled it to make.
|
since the 1500s, when an unknown printer took a galley of type
|
||||||
|
and scrambled it to make.
|
||||||
</p>
|
</p>
|
||||||
</FAQ>
|
</FAQ>
|
||||||
</Fade>
|
</Fade>
|
||||||
|
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<FAQ title="Is my data secure?">
|
<FAQ title="Is my data secure?">
|
||||||
<p>
|
<p>
|
||||||
Cras justo odio, dapibus ac facilisis in, egestas eget quam. Sed posuere consectetur est at lobortis.
|
Cras justo odio, dapibus ac facilisis in, egestas eget quam.
|
||||||
|
Sed posuere consectetur est at lobortis.
|
||||||
</p>
|
</p>
|
||||||
</FAQ>
|
</FAQ>
|
||||||
</Fade>
|
</Fade>
|
||||||
|
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<FAQ title="How does Sia compare to other decentralized storage solutions?">
|
<FAQ title="How does Sia compare to other decentralized storage solutions?">
|
||||||
<p>
|
<p>
|
||||||
Cras justo odio, dapibus ac facilisis in, egestas eget quam. Sed posuere consectetur est at lobortis.
|
Cras justo odio, dapibus ac facilisis in, egestas eget quam.
|
||||||
|
Sed posuere consectetur est at lobortis.
|
||||||
</p>
|
</p>
|
||||||
</FAQ>
|
</FAQ>
|
||||||
</Fade>
|
</Fade>
|
||||||
|
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<FAQ title="How long will my files be available?">
|
<FAQ title="How long will my files be available?">
|
||||||
<p>
|
<p>
|
||||||
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer
|
Lorem Ipsum has been the industry's standard dummy text ever
|
||||||
took a galley of type and scrambled it to make a type specimen book.
|
since the 1500s, when an unknown printer took a galley of type
|
||||||
|
and scrambled it to make a type specimen book.
|
||||||
</p>
|
</p>
|
||||||
</FAQ>
|
</FAQ>
|
||||||
</Fade>
|
</Fade>
|
||||||
|
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<a className="more more-faq" href="https://support.sia.tech/">
|
<a className="more more-faq" href="https://support.sia.tech/">
|
||||||
View more faq
|
View more faq
|
||||||
<Arrow />
|
<Arrow />
|
||||||
|
@ -147,6 +166,6 @@ export default class HomeNetwork extends Component {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +1,42 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import Fade from 'react-reveal/Fade'
|
import Fade from "react-reveal/Fade";
|
||||||
import Reveal from 'react-reveal/Reveal'
|
import Reveal from "react-reveal/Reveal";
|
||||||
|
|
||||||
import './HomeSamples.scss'
|
import "./HomeSamples.scss";
|
||||||
import { Sample } from '../'
|
import { Sample } from "../";
|
||||||
|
|
||||||
const samples = [
|
const samples = [
|
||||||
{ type: 'HTML', url: '#' },
|
{ type: "HTML", url: "#" },
|
||||||
{ type: 'PDF', url: '#' },
|
{ type: "PDF", url: "#" },
|
||||||
{ type: 'Image', url: '#' },
|
{ type: "Image", url: "#" },
|
||||||
{ type: 'Audio', url: '#' },
|
{ type: "Audio", url: "#" },
|
||||||
{ type: 'Video', url: '#' },
|
{ type: "Video", url: "#" },
|
||||||
{ type: 'JSON', url: '#' },
|
{ type: "JSON", url: "#" },
|
||||||
{ type: 'Dapps', url: '#' },
|
{ type: "Dapps", url: "#" }
|
||||||
]
|
];
|
||||||
|
|
||||||
export default function HomeSamples() {
|
export default function HomeSamples() {
|
||||||
return (
|
return (
|
||||||
<div className="home-samples">
|
<div className="home-samples">
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<p>
|
<p>
|
||||||
Skynet has SDKs for popular programming languages which integrate seamlessly with existing applications. Above
|
Skynet has SDKs for popular programming languages which integrate
|
||||||
are a few code snippets for uploading and downloading data from Skynet.
|
seamlessly with existing applications. Above are a few code snippets
|
||||||
|
for uploading and downloading data from Skynet.
|
||||||
</p>
|
</p>
|
||||||
</Fade>
|
</Fade>
|
||||||
|
|
||||||
<Reveal effect="active">
|
<Reveal effect="active">
|
||||||
<div className="home-samples-samples">
|
<div className="home-samples-samples">
|
||||||
{samples.map((sample, i) => (
|
{samples.map((sample, i) => (
|
||||||
<Sample className={`fadeInUp delay${(i + 1) * 2}`} key={`${i}-${sample.url}`} {...sample} />
|
<Sample
|
||||||
|
className={`fadeInUp delay${i + 1}`}
|
||||||
|
key={`${i}-${sample.url}`}
|
||||||
|
{...sample}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</Reveal>
|
</Reveal>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from "react";
|
||||||
import Fade from 'react-reveal/Fade'
|
import Fade from "react-reveal/Fade";
|
||||||
|
|
||||||
import './HomeStay.scss'
|
import "./HomeStay.scss";
|
||||||
import { SocialLink, CircleIcon, Mailing } from '../'
|
import { SocialLink, CircleIcon, Mailing } from "../";
|
||||||
import { SmallOrb, Pyramid } from '../../svg'
|
import { SmallOrb, Pyramid } from "../../svg";
|
||||||
|
|
||||||
export default class HomeStay extends Component {
|
export default class HomeStay extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="home-stay">
|
<div className="home-stay">
|
||||||
<header className="home-stay-header">
|
<header className="home-stay-header">
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<div className="home-stay-divider">
|
<div className="home-stay-divider">
|
||||||
<CircleIcon>
|
<CircleIcon>
|
||||||
<Pyramid />
|
<Pyramid />
|
||||||
|
@ -20,7 +20,7 @@ export default class HomeStay extends Component {
|
||||||
<div className="small-divider" />
|
<div className="small-divider" />
|
||||||
</div>
|
</div>
|
||||||
</Fade>
|
</Fade>
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<h2>
|
<h2>
|
||||||
Stay up to date with
|
Stay up to date with
|
||||||
<br />
|
<br />
|
||||||
|
@ -31,27 +31,27 @@ export default class HomeStay extends Component {
|
||||||
|
|
||||||
<div className="home-stay-flex">
|
<div className="home-stay-flex">
|
||||||
<div className="home-stay-left">
|
<div className="home-stay-left">
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<p>
|
<p>
|
||||||
Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Cras justo odio, dapibus ac
|
Integer posuere erat a ante venenatis dapibus posuere velit
|
||||||
facilisis in.
|
aliquet. Cras justo odio, dapibus ac facilisis in.
|
||||||
</p>
|
</p>
|
||||||
</Fade>
|
</Fade>
|
||||||
|
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<Mailing id="check1" />
|
<Mailing id="check1" />
|
||||||
</Fade>
|
</Fade>
|
||||||
|
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<p className="disclaimer-text">
|
<p className="disclaimer-text">
|
||||||
Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Cras justo odio, dapibus ac
|
Integer posuere erat a ante venenatis dapibus posuere velit
|
||||||
facilisis in.
|
aliquet. Cras justo odio, dapibus ac facilisis in.
|
||||||
</p>
|
</p>
|
||||||
</Fade>
|
</Fade>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul className="home-stay-right">
|
<ul className="home-stay-right">
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<li>
|
<li>
|
||||||
<SocialLink
|
<SocialLink
|
||||||
icon="github"
|
icon="github"
|
||||||
|
@ -65,7 +65,7 @@ export default class HomeStay extends Component {
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</Fade>
|
</Fade>
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<li>
|
<li>
|
||||||
<SocialLink
|
<SocialLink
|
||||||
icon="discord"
|
icon="discord"
|
||||||
|
@ -75,7 +75,7 @@ export default class HomeStay extends Component {
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</Fade>
|
</Fade>
|
||||||
<Fade distance="40px" bottom>
|
<Fade duration={700} distance="40px" bottom>
|
||||||
<li>
|
<li>
|
||||||
<SocialLink
|
<SocialLink
|
||||||
icon="twitter"
|
icon="twitter"
|
||||||
|
@ -88,6 +88,6 @@ export default class HomeStay extends Component {
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
import Reveal from 'react-reveal/Reveal'
|
import Reveal from "react-reveal/Reveal";
|
||||||
|
|
||||||
import './HomeTop.scss'
|
import "./HomeTop.scss";
|
||||||
import { Skynet, Deco1, Deco2 } from '../../svg'
|
import { Skynet, Deco1, Deco2 } from "../../svg";
|
||||||
|
|
||||||
export default function HomeTop() {
|
export default function HomeTop() {
|
||||||
return (
|
return (
|
||||||
|
@ -12,11 +12,14 @@ export default function HomeTop() {
|
||||||
|
|
||||||
<h1 className="fadeInUp delay2">Build the Future Web.</h1>
|
<h1 className="fadeInUp delay2">Build the Future Web.</h1>
|
||||||
|
|
||||||
<p className="fadeInUp delay4">Skynet is a decentralized file sharing and content distribution protocol.</p>
|
<p className="fadeInUp delay3">
|
||||||
|
Skynet is a decentralized file sharing and content distribution
|
||||||
|
protocol.
|
||||||
|
</p>
|
||||||
|
|
||||||
<Deco1 className="deco-1 fadeInUp delay8" />
|
<Deco1 className="deco-1 fadeInUp delay6" />
|
||||||
<Deco2 className="deco-2 fadeInUp delay8" />
|
<Deco2 className="deco-2 fadeInUp delay6" />
|
||||||
</div>
|
</div>
|
||||||
</Reveal>
|
</Reveal>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../variables.scss';
|
@import "../../variables.scss";
|
||||||
|
|
||||||
.home-top {
|
.home-top {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -47,8 +47,8 @@
|
||||||
.deco-1 {
|
.deco-1 {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 100%;
|
left: 100%;
|
||||||
bottom: 54%;
|
bottom: 25%;
|
||||||
margin-left: -20px;
|
margin-left: 20px;
|
||||||
animation: 6s float infinite;
|
animation: 6s float infinite;
|
||||||
|
|
||||||
@media (min-width: 591px) {
|
@media (min-width: 591px) {
|
||||||
|
@ -59,8 +59,8 @@
|
||||||
.deco-2 {
|
.deco-2 {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 100%;
|
left: 100%;
|
||||||
bottom: 34%;
|
bottom: 5%;
|
||||||
margin-left: -40px;
|
margin-left: -15px;
|
||||||
animation: 8s float infinite;
|
animation: 8s float infinite;
|
||||||
|
|
||||||
@media (min-width: 591px) {
|
@media (min-width: 591px) {
|
||||||
|
|
|
@ -1,43 +1,47 @@
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from "react";
|
||||||
import classNames from 'classnames'
|
import classNames from "classnames";
|
||||||
import Dropzone from 'react-dropzone'
|
import Dropzone from "react-dropzone";
|
||||||
import Reveal from 'react-reveal/Reveal'
|
import Reveal from "react-reveal/Reveal";
|
||||||
|
|
||||||
import { Button, UploadFile } from '../'
|
import { Button, UploadFile } from "../";
|
||||||
import { Deco3, Deco4, Deco5 } from '../../svg'
|
import { Deco3, Deco4, Deco5 } from "../../svg";
|
||||||
import './HomeUpload.scss'
|
import "./HomeUpload.scss";
|
||||||
|
|
||||||
export default class HomeUpload extends Component {
|
export default class HomeUpload extends Component {
|
||||||
state = { files: [] }
|
state = { files: [] };
|
||||||
|
|
||||||
handleDrop = async acceptedFiles => {
|
handleDrop = async acceptedFiles => {
|
||||||
this.setState({
|
this.setState({
|
||||||
files: [
|
files: [
|
||||||
...acceptedFiles.map(file => {
|
...acceptedFiles.map(file => {
|
||||||
return { file, status: 'uploading' }
|
return { file, status: "uploading" };
|
||||||
}),
|
}),
|
||||||
...this.state.files,
|
...this.state.files
|
||||||
],
|
]
|
||||||
})
|
});
|
||||||
|
|
||||||
acceptedFiles.forEach(async (file) => {
|
acceptedFiles.forEach(async file => {
|
||||||
const url = `https://siasky.net/api/skyfile?filename=${file.name}`
|
const url = `https://siasky.net/api/skyfile?filename=${file.name}`;
|
||||||
const fd = new FormData()
|
const fd = new FormData();
|
||||||
fd.append("file", file)
|
fd.append("file", file);
|
||||||
|
|
||||||
const onComplete = (status, skylink) => {
|
const onComplete = (status, skylink) => {
|
||||||
this.setState((state) => {
|
this.setState(state => {
|
||||||
const index = state.files.findIndex((f) => f.file === file);
|
const index = state.files.findIndex(f => f.file === file);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
files: [
|
files: [
|
||||||
...state.files.slice(0, index),
|
...state.files.slice(0, index),
|
||||||
{ ...state.files[index], status, url: `https://siasky.net/${skylink}` },
|
{
|
||||||
|
...state.files[index],
|
||||||
|
status,
|
||||||
|
url: `https://siasky.net/${skylink}`
|
||||||
|
},
|
||||||
...state.files.slice(index + 1)
|
...state.files.slice(index + 1)
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
|
@ -47,26 +51,30 @@ export default class HomeUpload extends Component {
|
||||||
});
|
});
|
||||||
const { skylink } = await response.json();
|
const { skylink } = await response.json();
|
||||||
|
|
||||||
onComplete('complete', skylink);
|
onComplete("complete", skylink);
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
onComplete('error');
|
onComplete("error");
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Reveal effect="active">
|
<Reveal effect="active">
|
||||||
<div className="home-upload">
|
<div className="home-upload">
|
||||||
<div className="home-upload-box fadeInUp delay6">
|
<div className="home-upload-box fadeInUp delay4">
|
||||||
<Dropzone onDrop={acceptedFiles => this.handleDrop(acceptedFiles)}>
|
<Dropzone onDrop={acceptedFiles => this.handleDrop(acceptedFiles)}>
|
||||||
{({ getRootProps, getInputProps, isDragActive }) => (
|
{({ getRootProps, getInputProps, isDragActive }) => (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={classNames('home-upload-dashed', { 'drop-active': isDragActive })}
|
className={classNames("home-upload-dashed", {
|
||||||
|
"drop-active": isDragActive
|
||||||
|
})}
|
||||||
{...getRootProps()}
|
{...getRootProps()}
|
||||||
>
|
>
|
||||||
<span className="home-upload-text">Drag & drop your file(s) here to pin</span>
|
<span className="home-upload-text">
|
||||||
|
Drag & drop your file(s) here to pin
|
||||||
|
</span>
|
||||||
<Button>Browse</Button>
|
<Button>Browse</Button>
|
||||||
</div>
|
</div>
|
||||||
<input {...getInputProps()} className="offscreen" />
|
<input {...getInputProps()} className="offscreen" />
|
||||||
|
@ -77,22 +85,23 @@ export default class HomeUpload extends Component {
|
||||||
{this.state.files.length > 0 && (
|
{this.state.files.length > 0 && (
|
||||||
<div className="home-uploaded-files">
|
<div className="home-uploaded-files">
|
||||||
{this.state.files.map((file, i) => {
|
{this.state.files.map((file, i) => {
|
||||||
return <UploadFile key={i} {...file} />
|
return <UploadFile key={i} {...file} />;
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="bottom-text fadeInUp delay8">
|
<p className="bottom-text fadeInUp delay5">
|
||||||
Once a file has been uploaded, a 46 byte link called a 'Skylink' is generated. That link can then be shared
|
Once a file has been uploaded, a 46 byte link called a 'Skylink' is
|
||||||
with anyone to fetch the file from Skynet.
|
generated. That link can then be shared with anyone to fetch the
|
||||||
|
file from Skynet.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<Deco3 className="deco-3 fadeInUp delay8" />
|
<Deco3 className="deco-3 fadeInUp delay6" />
|
||||||
<Deco4 className="deco-4 fadeInUp delay8" />
|
<Deco4 className="deco-4 fadeInUp delay6" />
|
||||||
<Deco5 className="deco-5 fadeInUp delay8" />
|
<Deco5 className="deco-5 fadeInUp delay6" />
|
||||||
</div>
|
</div>
|
||||||
</Reveal>
|
</Reveal>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../variables.scss';
|
@import "../../variables.scss";
|
||||||
|
|
||||||
.home-upload {
|
.home-upload {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -19,7 +19,8 @@
|
||||||
.home-upload-box {
|
.home-upload-box {
|
||||||
background: $white;
|
background: $white;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 8px 24px 0 rgba(90, 94, 91, 0.15), 0 2px 4px 0 rgba(0, 0, 0, 0.05);
|
box-shadow: 0 8px 24px 0 rgba(90, 94, 91, 0.15),
|
||||||
|
0 2px 4px 0 rgba(0, 0, 0, 0.05);
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,10 +98,14 @@
|
||||||
|
|
||||||
.home-uploaded-files {
|
.home-uploaded-files {
|
||||||
border: solid 1px #c5cec7;
|
border: solid 1px #c5cec7;
|
||||||
padding: 0 40px;
|
padding: 0 20px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
||||||
|
@media (min-width: $largebp) {
|
||||||
|
padding: 0 40px;
|
||||||
|
}
|
||||||
|
|
||||||
.upload-file + .upload-file {
|
.upload-file + .upload-file {
|
||||||
border-top: 1px solid rgba(197, 206, 199, 0.4);
|
border-top: 1px solid rgba(197, 206, 199, 0.4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,73 +1,78 @@
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from "react";
|
||||||
|
|
||||||
import './UploadFile.scss'
|
import "./UploadFile.scss";
|
||||||
import { LoadingSpinner } from '../'
|
import { LoadingSpinner } from "../";
|
||||||
import { File, FileCheck, FileError, Copy } from '../../svg'
|
import { File, FileCheck, FileError, Copy } from "../../svg";
|
||||||
|
|
||||||
export default class UploadFile extends Component {
|
export default class UploadFile extends Component {
|
||||||
state = {
|
state = {
|
||||||
copied: false,
|
copied: false
|
||||||
}
|
};
|
||||||
|
|
||||||
getIcon = () => {
|
getIcon = () => {
|
||||||
const { status } = this.props
|
const { status } = this.props;
|
||||||
|
|
||||||
if (status === 'uploading' || status === 'processing') {
|
if (status === "uploading" || status === "processing") {
|
||||||
return <File />
|
return <File />;
|
||||||
} else if (status === 'error') {
|
} else if (status === "error") {
|
||||||
return <FileError />
|
return <FileError />;
|
||||||
} else {
|
} else {
|
||||||
return <FileCheck />
|
return <FileCheck />;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
copyToClipboard = e => {
|
copyToClipboard = e => {
|
||||||
this.urlRef.current.select()
|
this.urlRef.current.select();
|
||||||
document.execCommand('copy')
|
document.execCommand("copy");
|
||||||
e.target.focus()
|
e.target.focus();
|
||||||
|
|
||||||
this.setState({ copied: true }, () => {
|
this.setState({ copied: true }, () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.setState({ copied: false })
|
this.setState({ copied: false });
|
||||||
}, 1500)
|
}, 1500);
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
urlRef = React.createRef()
|
urlRef = React.createRef();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { file, url, status } = this.props
|
const { file, url, status } = this.props;
|
||||||
const copyText = this.state.copied ? 'Copied!' : 'Copy to clipboard'
|
const copyText = this.state.copied ? "Copied!" : "Copy to clipboard";
|
||||||
return (
|
return (
|
||||||
<div className="upload-file">
|
<div className="upload-file">
|
||||||
<div className="upload-file-icon">{this.getIcon()}</div>
|
<div className="upload-file-icon">{this.getIcon()}</div>
|
||||||
<div className="upload-file-text">
|
<div className="upload-file-text">
|
||||||
<h3>{file.name}</h3>
|
<h3>{file.name}</h3>
|
||||||
<p>
|
<p>
|
||||||
{status === 'uploading' && 'Uploading...'}
|
{status === "uploading" && "Uploading..."}
|
||||||
{status === 'processing' && 'Processing...'}
|
{status === "processing" && "Processing..."}
|
||||||
{status === 'error' && <span className="red-text">Error processing file.</span>}
|
{status === "error" && (
|
||||||
{status === 'complete' && (
|
<span className="red-text">Error processing file.</span>
|
||||||
|
)}
|
||||||
|
{status === "complete" && (
|
||||||
<a href={url} className="url green-text">
|
<a href={url} className="url green-text">
|
||||||
{url}
|
{url}
|
||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{(status === 'uploading' || status === 'processing') && (
|
{(status === "uploading" || status === "processing") && (
|
||||||
<div className="upload-file-loading">
|
<div className="upload-file-loading">
|
||||||
<LoadingSpinner />
|
<LoadingSpinner />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{status === 'complete' && (
|
{status === "complete" && (
|
||||||
<button onClick={this.copyToClipboard} className="upload-file-copy">
|
<button onClick={this.copyToClipboard} className="upload-file-copy">
|
||||||
<p className="upload-file-copy-tooltip">{copyText}</p>
|
<p className="upload-file-copy-tooltip">{copyText}</p>
|
||||||
|
<div className="upload-file-copy-button">
|
||||||
|
Copy Link
|
||||||
<Copy />
|
<Copy />
|
||||||
|
</div>
|
||||||
<textarea value={url} ref={this.urlRef} />
|
<textarea value={url} ref={this.urlRef} />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../variables.scss';
|
@import "../../variables.scss";
|
||||||
|
|
||||||
.upload-file {
|
.upload-file {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -97,8 +97,36 @@
|
||||||
top: 100%;
|
top: 100%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
margin-left: -6px;
|
margin-left: -6px;
|
||||||
content: '';
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
box-shadow: 0 2px 8px 0 rgba(23, 25, 23, 0.2);
|
box-shadow: 0 2px 8px 0 rgba(23, 25, 23, 0.2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.upload-file-copy-button {
|
||||||
|
border: 1px solid $green;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: $green;
|
||||||
|
line-height: 40px;
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 0 10px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 700;
|
||||||
|
transition: 0.2s color, 0.2s background-color;
|
||||||
|
|
||||||
|
@media (min-width: $largebp) {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 0 15px;
|
||||||
|
line-height: 46px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $green;
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,41 +1,41 @@
|
||||||
@import './variables.scss';
|
@import "./variables.scss";
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Haas Grot Disp';
|
font-family: "Haas Grot Disp";
|
||||||
src: url('/fonts/hinted-subset-HaasGrotDispR-55Roman.woff2') format('woff2'),
|
src: url("/fonts/hinted-subset-HaasGrotDispR-55Roman.woff2") format("woff2"),
|
||||||
url('/fonts/hinted-subset-HaasGrotDispR-55Roman.woff') format('woff');
|
url("/fonts/hinted-subset-HaasGrotDispR-55Roman.woff") format("woff");
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Haas Grot Disp';
|
font-family: "Haas Grot Disp";
|
||||||
src: url('/fonts/hinted-subset-HaasGrotDispR-65Medium.woff2') format('woff2'),
|
src: url("/fonts/hinted-subset-HaasGrotDispR-65Medium.woff2") format("woff2"),
|
||||||
url('/fonts/hinted-subset-HaasGrotDispR-65Medium.woff') format('woff');
|
url("/fonts/hinted-subset-HaasGrotDispR-65Medium.woff") format("woff");
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Haas Grot Text';
|
font-family: "Haas Grot Text";
|
||||||
src: url('/fonts/hinted-subset-HaasGrotTextR-75Bold.woff2') format('woff2'),
|
src: url("/fonts/hinted-subset-HaasGrotTextR-75Bold.woff2") format("woff2"),
|
||||||
url('/fonts/hinted-subset-HaasGrotTextR-75Bold.woff') format('woff');
|
url("/fonts/hinted-subset-HaasGrotTextR-75Bold.woff") format("woff");
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Haas Grot Text';
|
font-family: "Haas Grot Text";
|
||||||
src: url('/fonts/hinted-subset-HaasGrotTextR-65Medium.woff2') format('woff2'),
|
src: url("/fonts/hinted-subset-HaasGrotTextR-65Medium.woff2") format("woff2"),
|
||||||
url('/fonts/hinted-subset-HaasGrotTextR-65Medium.woff') format('woff');
|
url("/fonts/hinted-subset-HaasGrotTextR-65Medium.woff") format("woff");
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Haas Grot Text';
|
font-family: "Haas Grot Text";
|
||||||
src: url('/fonts/hinted-subset-HaasGrotTextR-55Roman.woff2') format('woff2'),
|
src: url("/fonts/hinted-subset-HaasGrotTextR-55Roman.woff2") format("woff2"),
|
||||||
url('/fonts/hinted-subset-HaasGrotTextR-55Roman.woff') format('woff');
|
url("/fonts/hinted-subset-HaasGrotTextR-55Roman.woff") format("woff");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
@ -88,10 +88,10 @@ textarea {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type='email'],
|
input[type="email"],
|
||||||
input[type='text'],
|
input[type="text"],
|
||||||
input[type='password'],
|
input[type="password"],
|
||||||
input[type='search'] {
|
input[type="search"] {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -99,9 +99,9 @@ input[type='search'] {
|
||||||
a,
|
a,
|
||||||
button,
|
button,
|
||||||
label,
|
label,
|
||||||
input[type='submit'],
|
input[type="submit"],
|
||||||
input[type='checkbox'],
|
input[type="checkbox"],
|
||||||
input[type='radio'] {
|
input[type="radio"] {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ svg {
|
||||||
.fadeInUp {
|
.fadeInUp {
|
||||||
transform: translateY(40px);
|
transform: translateY(40px);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: 1s opacity, 1s transform;
|
transition: 0.7s opacity, 0.7s transform;
|
||||||
|
|
||||||
.active & {
|
.active & {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
import React from 'react'
|
import React from "react";
|
||||||
|
|
||||||
export default function Copy(props) {
|
export default function Copy(props) {
|
||||||
return (
|
return (
|
||||||
<svg width={18} height={18} viewBox="0 0 18 18" {...props}>
|
<svg width={12} height={14} viewBox="0 0 12 14" {...props}>
|
||||||
<path
|
<path
|
||||||
d="M15 13v2a2 2 0 01-2 2H3a2 2 0 01-2-2V5a2 2 0 012-2h2m2.464 3.293L6.05 7.707a3 3 0 104.243 4.243l1.414-1.414h0m-1.414-7.072l1.414-1.414a3 3 0 114.243 4.243l-1.414 1.414h0M8.879 9.121L13.12 4.88"
|
d="M8 1H4a3 3 0 00-3 3v6h0m4-6h5a1 1 0 011 1v7a1 1 0 01-1 1H5a1 1 0 01-1-1V5a1 1 0 011-1z"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
fill="none"
|
fill="none"
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue