Initial pass at download page.
This commit is contained in:
parent
9727051290
commit
5b5e4f9445
|
@ -13,6 +13,7 @@ import CheckTransaction from 'containers/Tabs/CheckTransaction';
|
|||
import ErrorScreen from 'components/ErrorScreen';
|
||||
import PageNotFound from 'components/PageNotFound';
|
||||
import LogOutPrompt from 'components/LogOutPrompt';
|
||||
import DownloadPage from 'components/DownloadPage';
|
||||
import { TitleBar } from 'components/ui';
|
||||
import { Store } from 'redux';
|
||||
import { pollOfflineStatus } from 'actions/config';
|
||||
|
@ -70,6 +71,7 @@ export default class Root extends Component<Props, State> {
|
|||
<Route path="/sign-and-verify-message" component={SignAndVerifyMessage} />
|
||||
<Route path="/tx-status" component={CheckTransaction} exact={true} />
|
||||
<Route path="/pushTx" component={BroadcastTx} />
|
||||
<Route path="/download" component={DownloadPage} />
|
||||
<RouteNotFound />
|
||||
</Switch>
|
||||
</CaptureRouteNotFound>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 168 KiB |
|
@ -0,0 +1,122 @@
|
|||
@import 'common/sass/variables';
|
||||
|
||||
$screenshot-bleed: 200px;
|
||||
|
||||
@keyframes background-gradient {
|
||||
0%, 100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes screenshot-slide {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(20px) scale(0.97);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.DownloadPage {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
margin: 0 -3% -5rem;
|
||||
|
||||
@media (min-width: $screen-md) {
|
||||
margin: 0 -5rem -5rem;
|
||||
}
|
||||
|
||||
&-top {
|
||||
padding: $space * 2 $space $screenshot-bleed;
|
||||
color: #FFF;
|
||||
background: linear-gradient(-120deg, $ether-navy, $brand-primary, $ether-navy);
|
||||
background-size: 400% 400%;
|
||||
animation: background-gradient 40s ease infinite;
|
||||
}
|
||||
|
||||
&-title {
|
||||
margin-bottom: $space;
|
||||
}
|
||||
|
||||
&-description {
|
||||
font-size: $font-size-medium;
|
||||
max-width: 660px;
|
||||
margin: 0 auto $space * 2.5;
|
||||
opacity: 0.92;
|
||||
}
|
||||
|
||||
&-download {
|
||||
margin-bottom: $space * 2;
|
||||
|
||||
&-button {
|
||||
display: block;
|
||||
max-width: 320px;
|
||||
margin: 0 auto $space-sm;
|
||||
padding: $space 0;
|
||||
font-size: $font-size-medium;
|
||||
background: #FFF;
|
||||
border-radius: 4px;
|
||||
color: $text-color;
|
||||
transition: color 100ms ease, transform 100ms ease;
|
||||
|
||||
&:hover {
|
||||
color: $brand-primary;
|
||||
transform: translateY(-1px);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.fa {
|
||||
margin-left: $space-sm;
|
||||
}
|
||||
}
|
||||
|
||||
&-link {
|
||||
margin: 0 $space-sm;
|
||||
color: #FFF;
|
||||
opacity: 0.5;
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
color: #FFF;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-screenshot {
|
||||
display: block;
|
||||
max-width: 1020px;
|
||||
width: 100%;
|
||||
margin: -$screenshot-bleed auto $space * 4;
|
||||
animation: screenshot-slide 800ms ease 1;
|
||||
animation-delay: 1200ms;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
&-features {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: $space * 4;
|
||||
|
||||
&-feature {
|
||||
max-width: 320px;
|
||||
margin: 0 $space $space;
|
||||
|
||||
&-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
line-height: 80px;
|
||||
margin: 0 auto $space-sm;
|
||||
color: #FFF;
|
||||
font-size: 42px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
import React from 'react';
|
||||
import TabSection from 'containers/TabSection';
|
||||
import { NewTabLink } from 'components/ui';
|
||||
import ElectronOSX from 'assets/images/download/electron-osx.png';
|
||||
import './DownloadPage.scss';
|
||||
|
||||
const features = [
|
||||
{
|
||||
title: 'Secure',
|
||||
color: '#2ecc71',
|
||||
icon: 'lock',
|
||||
text: `
|
||||
Don’t worry about malicious browser extensions or wifi networks, the desktop
|
||||
MyCrypto app runs in a sandbox with local resources, so your private keys
|
||||
are safe
|
||||
`
|
||||
},
|
||||
{
|
||||
title: 'Work Offline',
|
||||
color: '#9b59b6',
|
||||
icon: 'wifi',
|
||||
text: `
|
||||
No internet? No problem. Everything you need to generate transactions is on
|
||||
your computer. You can also run your own node to control your environment 100%.
|
||||
`
|
||||
},
|
||||
{
|
||||
title: 'Always Yours',
|
||||
color: '#e67e22',
|
||||
icon: 'user',
|
||||
text: `
|
||||
It doesn't matter if mycrypto.com goes down, the app will always be yours.
|
||||
Everything is configurable, which means you’ll always have access to the
|
||||
blockchain with MyCrypto.
|
||||
`
|
||||
},
|
||||
{
|
||||
title: 'Open Source',
|
||||
color: '#34495e',
|
||||
icon: 'github',
|
||||
text: `
|
||||
Built with the community in mind, the MyCrypto app is completely open source.
|
||||
Anyone can audit the code, and contribute changes on Github.
|
||||
`
|
||||
}
|
||||
];
|
||||
|
||||
export default class DownloadPage extends React.Component<{}> {
|
||||
public render() {
|
||||
let os = 'the Desktop';
|
||||
const img = ElectronOSX;
|
||||
if (navigator.appVersion.includes('Win')) {
|
||||
os = 'Windows';
|
||||
} else if (navigator.appVersion.includes('Mac')) {
|
||||
os = 'OSX';
|
||||
} else if (navigator.appVersion.includes('Linux')) {
|
||||
os = 'Linux';
|
||||
} else if (navigator.appVersion.includes('X11')) {
|
||||
os = 'Unix';
|
||||
}
|
||||
|
||||
return (
|
||||
<TabSection hideHeader={true}>
|
||||
<div className="DownloadPage">
|
||||
<div className="DownloadPage-top">
|
||||
<h1 className="DownloadPage-title">Download MyCrypto for {os}</h1>
|
||||
<p className="DownloadPage-description">
|
||||
Run MyCrypto securely and offline with the desktop application. Powered by Electron,
|
||||
it's the same MyCrypto app, running in a sandboxed environment.
|
||||
</p>
|
||||
|
||||
<div className="DownloadPage-download">
|
||||
<NewTabLink
|
||||
className="DownloadPage-download-button"
|
||||
href="https://github.com/MyCryptoHQ/MyCrypto/releases/latest"
|
||||
>
|
||||
Download from Github <i className="fa fa-external-link" />
|
||||
</NewTabLink>
|
||||
<NewTabLink
|
||||
className="DownloadPage-download-link"
|
||||
href="https://github.com/MyCryptoHQ/MyCrypto/releases"
|
||||
>
|
||||
Release History
|
||||
</NewTabLink>
|
||||
<NewTabLink
|
||||
className="DownloadPage-download-link"
|
||||
href="https://github.com/MyCryptoHQ/MyCrypto/releases/latest"
|
||||
>
|
||||
Release Notes
|
||||
</NewTabLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<img className="DownloadPage-screenshot" src={img} />
|
||||
|
||||
<div className="DownloadPage-features">
|
||||
{features.map(ft => (
|
||||
<div className="DownloadPage-features-feature">
|
||||
<div
|
||||
className="DownloadPage-features-feature-icon"
|
||||
style={{
|
||||
backgroundColor: ft.color
|
||||
}}
|
||||
>
|
||||
<i className={`fa fa-${ft.icon}`} />
|
||||
</div>
|
||||
<h3 className="DownloadPage-features-feature-title">{ft.title}</h3>
|
||||
<p className="DownloadPage-features-feature-text">{ft.text}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</TabSection>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
import DownloadPage from './DownloadPage';
|
||||
export default DownloadPage;
|
|
@ -31,8 +31,16 @@ export interface AAttributes {
|
|||
|
||||
interface NewTabLinkProps extends AAttributes {
|
||||
href: string;
|
||||
content?: React.ReactElement<any> | string | string[] | number;
|
||||
children?: React.ReactElement<any> | string | string[] | number;
|
||||
content?:
|
||||
| React.ReactElement<any>
|
||||
| string
|
||||
| number
|
||||
| (string | number | React.ReactElement<string>)[];
|
||||
children?:
|
||||
| React.ReactElement<any>
|
||||
| string
|
||||
| number
|
||||
| (string | number | React.ReactElement<string>)[];
|
||||
}
|
||||
|
||||
export class NewTabLink extends React.Component<NewTabLinkProps> {
|
||||
|
|
|
@ -12,6 +12,7 @@ interface StateProps {
|
|||
}
|
||||
|
||||
interface OwnProps {
|
||||
hideHeader?: boolean;
|
||||
isUnavailableOffline?: boolean;
|
||||
children: string | React.ReactElement<string> | React.ReactElement<string>[];
|
||||
}
|
||||
|
@ -20,12 +21,12 @@ type Props = OwnProps & StateProps;
|
|||
|
||||
class TabSection extends Component<Props, {}> {
|
||||
public render() {
|
||||
const { isUnavailableOffline, children, isOffline, latestBlock } = this.props;
|
||||
const { isUnavailableOffline, children, isOffline, latestBlock, hideHeader } = this.props;
|
||||
|
||||
return (
|
||||
<div className="page-layout">
|
||||
<main>
|
||||
<Header />
|
||||
{!hideHeader && <Header />}
|
||||
<div className="Tab container">
|
||||
{isUnavailableOffline && isOffline ? <OfflineTab /> : children}
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue