Initial pass at download page.

This commit is contained in:
Will O'Beirne 2018-02-20 16:09:31 -05:00
parent 9727051290
commit 5b5e4f9445
No known key found for this signature in database
GPG Key ID: 44C190DB5DEAF9F6
7 changed files with 255 additions and 4 deletions

View File

@ -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

View File

@ -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%;
}
}
}
}

View File

@ -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: `
Dont 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 youll 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>
);
}
}

View File

@ -0,0 +1,2 @@
import DownloadPage from './DownloadPage';
export default DownloadPage;

View File

@ -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> {

View File

@ -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>