mirror of
https://github.com/nickzuber/meteorite.git
synced 2024-08-16 23:10:38 +03:00
New icons, login page
This commit is contained in:
parent
47bef328ea
commit
524bd451fa
2
now.json
2
now.json
@ -12,6 +12,8 @@
|
||||
{"src": "^/favicon.ico", "dest": "/iconCircle.png"},
|
||||
{"src": "^/iconCircle.png", "dest": "/iconCircle.png"},
|
||||
{"src": "^/app-icon.png", "dest": "/app-icon.png"},
|
||||
{"src": "^/new-app-icon.png", "dest": "/new-app-icon.png"},
|
||||
{"src": "^/new-app-icon-rounded.png", "dest": "/new-app-icon-rounded.png"},
|
||||
{"src": "^/manifest.json", "dest": "/manifest.json"},
|
||||
{"src": "^/asset-manifest.json", "dest": "/asset-manifest.json"},
|
||||
{"src": "^/service-worker.js", "headers": {"cache-control": "s-maxage=0"}, "dest": "/service-worker.js"},
|
||||
|
@ -3,12 +3,42 @@
|
||||
"name": "Meteorite – Smarter GitHub Notifications",
|
||||
"icons": [
|
||||
{
|
||||
"src": "app-icon.png",
|
||||
"src": "new-app-icon.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "new-app-icon.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "new-app-icon.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "new-app-icon.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "new-app-icon.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "app-icon-taskbar.png",
|
||||
"src": "new-app-icon.png",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "new-app-icon.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "new-app-icon-rounded.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
|
BIN
public/new-app-icon-rounded.png
Normal file
BIN
public/new-app-icon-rounded.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
BIN
public/new-app-icon.png
Normal file
BIN
public/new-app-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
143
src/components/Confetti/index.js
Normal file
143
src/components/Confetti/index.js
Normal file
@ -0,0 +1,143 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import {css, jsx} from '@emotion/core';
|
||||
|
||||
function color (rand) {
|
||||
// const c = [
|
||||
// '#4caf50',
|
||||
// '#e91e63',
|
||||
// '#4C84FF',
|
||||
// '#e6d435',
|
||||
// '#B424E6',
|
||||
// ];
|
||||
const c = [
|
||||
'#B424E6',
|
||||
'#1ACA6B',
|
||||
'#E62465',
|
||||
'#FFCD4C',
|
||||
'#4C84FF',
|
||||
'#E9519A',
|
||||
];
|
||||
return c[~~(c.length * rand)];
|
||||
}
|
||||
|
||||
function opacity (xid, max) {
|
||||
// Max value (best possible score).
|
||||
const cap = 1;
|
||||
// Best value to base distribution on (the center value).
|
||||
const best = Math.floor(max / 2);
|
||||
// How spread out the distribution is from the best value.
|
||||
const distribution = 8;
|
||||
const result = Math.min(1, cap * Math.pow(
|
||||
Math.E,
|
||||
(-0.5) * (Math.pow(xid - best, 2) / (Math.pow(distribution, 2)))
|
||||
));
|
||||
return Math.max(1 - result, 0.05) * 1.75;
|
||||
}
|
||||
|
||||
function range (min, max, rand) {
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(rand * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
function getConfetti (seed) {
|
||||
const stroke = color(seed);
|
||||
const rotation = ~~(seed * 180);
|
||||
|
||||
const svgs = [
|
||||
(
|
||||
<svg css={css`transform: rotate(${rotation}deg);`} width="12" height="9" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 0L11.1962 9H0.803848L6 0Z" fill={stroke}/>
|
||||
</svg>
|
||||
),
|
||||
(
|
||||
<svg css={css`transform: rotate(${rotation}deg);`} width="12" height="9" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M6 0L11.1962 9H0.803848L6 0Z"
|
||||
fill={stroke}
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
(
|
||||
<svg css={css`transform: rotate(${rotation}deg);`} width="14" height="18" viewBox="0 0 14 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M12 2C0.517508 6.06139 6.6799 11.5502 2 16"
|
||||
stroke={stroke}
|
||||
stroke-width="4"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
(
|
||||
<svg css={css`transform: rotate(${rotation}deg);`} width="8" height="13" viewBox="0 0 8 13" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M4 0L8 6.5L4 13L0 6.5L4 0Z"
|
||||
fill={stroke}
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
(
|
||||
<svg css={css`transform: rotate(${rotation}deg);`} width="8" height="14" viewBox="0 0 8 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M8 6.6393C8 9.44331 2.33469 14 0.577298 14C-1.1801 14 1.63591 9.44331 1.63591 6.6393C1.63591 3.83529 -0.119245 0 1.63815 0C3.39555 0 8 3.83529 8 6.6393Z"
|
||||
fill={stroke}
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
(
|
||||
<svg css={css`transform: rotate(${rotation}deg);`} width="10" height="12" viewBox="0 0 10 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M9.15408 5.477C8.15168 8.67191 7 13.5 5.15408 11.5C3.30816 9.5 2.90284 9.34138 1.15517 5.47695C-2.00009 -1.49991 3.99732 1.50011 5.15408 3.977C6.15408 1.47707 11.5 -2 9.15408 5.477Z"
|
||||
fill={stroke}/>
|
||||
</svg>
|
||||
),
|
||||
(
|
||||
<svg css={css`transform: rotate(${rotation}deg);`} width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="5" cy="5" r="5" fill={stroke}/>
|
||||
</svg>
|
||||
)
|
||||
];
|
||||
// css={css`transform: rotate(${rotation}deg);`}
|
||||
|
||||
return svgs[~~(seed * svgs.length)];
|
||||
}
|
||||
|
||||
const Confetti = ({offset, row, seed, index, max}) => {
|
||||
const start = row * 160;
|
||||
const end = start + 160;
|
||||
const topDelta = range(start, end, seed) - 120;
|
||||
const fade = opacity(index, max);
|
||||
offset -= 320;
|
||||
return (
|
||||
<div css={css`
|
||||
z-index: 1;
|
||||
opacity: ${fade};
|
||||
transform: scale(1.2);
|
||||
position: absolute;
|
||||
left: ${offset}px;
|
||||
top: ${topDelta}px;
|
||||
`}
|
||||
>
|
||||
{getConfetti(seed)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ConfettiSection ({spacing = 82, amount = 18}) {
|
||||
const row = new Array(amount).fill(0).map((_, i) => i * spacing);
|
||||
|
||||
return (
|
||||
<div css={css`
|
||||
z-index: 0;
|
||||
`}>
|
||||
{row.map((offset, i) => <Confetti index={i} row={0} offset={offset} seed={Math.random()} max={amount} />)}
|
||||
{row.map((offset, i) => <Confetti index={i} row={1} offset={offset} seed={Math.random()} max={amount} />)}
|
||||
{row.map((offset, i) => <Confetti index={i} row={2} offset={offset} seed={Math.random()} max={amount} />)}
|
||||
{row.map((offset, i) => <Confetti index={i} row={3} offset={offset} seed={Math.random()} max={amount} />)}
|
||||
{row.map((offset, i) => <Confetti index={i} row={4} offset={offset} seed={Math.random()} max={amount} />)}
|
||||
{row.map((offset, i) => <Confetti index={i} row={5} offset={offset} seed={Math.random()} max={amount} />)}
|
||||
</div>
|
||||
);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,58 +1,82 @@
|
||||
import React from 'react';
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Link } from "@reach/router";
|
||||
import styled from '@emotion/styled';
|
||||
import {css, jsx} from '@emotion/core';
|
||||
import React from 'react';
|
||||
import { routes } from '../../constants';
|
||||
import { AuthenticationButton } from '../../components/buttons';
|
||||
import LoadingIcon from '../../components/LoadingIcon';
|
||||
import ErrorMessage from '../../components/ErrorMessage';
|
||||
import ConfettiSection from '../../components/Confetti';
|
||||
import '../../styles/gradient.css';
|
||||
|
||||
const Container = styled('div')({
|
||||
position: 'relative',
|
||||
background: '#fff',
|
||||
borderRadius: 4,
|
||||
margin: '0 auto',
|
||||
padding: '24px 48px 76px',
|
||||
width: 300,
|
||||
boxShadow: '0 50px 100px rgba(50,50,93,.1), 0 15px 35px rgba(50,50,93,.15), 0 5px 15px rgba(0,0,0,.1)'
|
||||
});
|
||||
const WHITE = 'rgb(255, 254, 252)';
|
||||
|
||||
const ButtonsContainer = styled('div')({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
position: 'absolute',
|
||||
bottom: 24,
|
||||
left: 48,
|
||||
right: 48,
|
||||
'a': {
|
||||
margin: 0
|
||||
const Card = styled('div')`
|
||||
position: relative;
|
||||
width: 280px;
|
||||
min-height: 100px;
|
||||
margin: 32px auto 0;
|
||||
background: #ffffff;
|
||||
border: 1px solid #E5E6EB;
|
||||
box-shadow: rgba(84, 70, 35, 0) 0px 2px 8px, rgba(84,70,35,0.15) 0px 1px 3px;
|
||||
border-radius: 6px;
|
||||
padding: 24px 32px 52px;
|
||||
`;
|
||||
|
||||
const ButtonsContainer = styled('div')`
|
||||
display: flex;
|
||||
justifyContent: space-between;
|
||||
position: absolute;
|
||||
bottom: 24;
|
||||
left: 48;
|
||||
right: 48;
|
||||
|
||||
a {
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
padding: 4px 12px;
|
||||
border-radius: 4px;
|
||||
flex-shrink: 0;
|
||||
font-size: 15px;
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
font-weight: 500;
|
||||
transition: all 200ms ease;
|
||||
&:hover {
|
||||
background: rgba(55, 53, 47, 0.08);
|
||||
}
|
||||
&:active {
|
||||
background: rgba(55, 53, 47, 0.16);
|
||||
}
|
||||
}
|
||||
});
|
||||
`;
|
||||
|
||||
export default function Scene ({ loading, error, loggedOut, ...props }) {
|
||||
return (
|
||||
<div className="container-gradient" style={{
|
||||
width: '100%',
|
||||
position: 'relative',
|
||||
flexDirection: 'column',
|
||||
height: '100vh',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<Container>
|
||||
<div css={css`
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: ${WHITE};
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
max-width: 1420px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
`}>
|
||||
<ConfettiSection spacing={100} amount={20} />
|
||||
<Card>
|
||||
<h3>Authenticate with GitHub</h3>
|
||||
{error ? (
|
||||
<React.Fragment>
|
||||
<p>Log in with GitHub and we'll start organizing and sorting all of your notifications.</p>
|
||||
<ErrorMessage>Oops, looks like something went wrong. Try again?</ErrorMessage>
|
||||
<ButtonsContainer>
|
||||
<div className="button-container-alt">
|
||||
<Link style={{boxShadow: '0 0 0'}} to={routes.HOME}>go back</Link>
|
||||
</div>
|
||||
<div className="button-container-alt">
|
||||
<AuthenticationButton style={{boxShadow: '0 0 0'}} />
|
||||
</div>
|
||||
<Link style={{boxShadow: '0 0 0'}} to={routes.HOME}>Go back</Link>
|
||||
<AuthenticationButton style={{boxShadow: '0 0 0'}} />
|
||||
</ButtonsContainer>
|
||||
</React.Fragment>
|
||||
) : loading ? (
|
||||
@ -61,18 +85,14 @@ export default function Scene ({ loading, error, loggedOut, ...props }) {
|
||||
<React.Fragment>
|
||||
<p>Log in with GitHub and we'll start organizing and sorting all of your notifications.</p>
|
||||
<ButtonsContainer>
|
||||
<div className="button-container-alt">
|
||||
<Link style={{boxShadow: '0 0 0'}} to={routes.HOME}>go back</Link>
|
||||
</div>
|
||||
<div className="button-container-alt">
|
||||
<AuthenticationButton style={{boxShadow: '0 0 0'}} />
|
||||
</div>
|
||||
<Link style={{boxShadow: '0 0 0'}} to={routes.HOME}>Go back</Link>
|
||||
<AuthenticationButton style={{boxShadow: '0 0 0'}} />
|
||||
</ButtonsContainer>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<span>logged in!</span>
|
||||
)}
|
||||
</Container>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user