Work on mobile, more home page progress
3
now.json
@ -9,7 +9,8 @@
|
||||
}],
|
||||
"routes": [
|
||||
{"src": "^/static/(.*)", "dest": "/static/$1"},
|
||||
{"src": "^/favicon.ico", "dest": "/favicon.ico"},
|
||||
{"src": "^/favicon.ico", "dest": "/iconCircle.png"},
|
||||
{"src": "^/iconCircle.png", "dest": "/iconCircle.png"},
|
||||
{"src": "^/manifest.json", "dest": "/manifest.json"},
|
||||
{"src": "^/(.*)", "dest": "/index.html"}
|
||||
],
|
||||
|
@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/iconCircle.png">
|
||||
<!-- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
|
||||
<meta name="theme-color" content="#24292e">
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 10 KiB |
BIN
src/images/logos/react-logo.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
src/images/logos/remote-hq-logo.png
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
src/images/logos/robin-logo.png
Normal file
After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 11 KiB |
BIN
src/images/regular-screenshot.png
Normal file
After Width: | Height: | Size: 285 KiB |
BIN
src/images/safari-header-original.png
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
src/images/safari-header.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
src/images/screenshots/iphone-x-mockup.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/images/screenshots/iphone-x.png
Normal file
After Width: | Height: | Size: 310 KiB |
BIN
src/images/traditional-screenshot.png
Normal file
After Width: | Height: | Size: 363 KiB |
@ -2,15 +2,20 @@
|
||||
|
||||
import React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import {css, jsx, keyframes} from '@emotion/core';
|
||||
import useComponentSize from '@rehooks/component-size'
|
||||
import {css, jsx} from '@emotion/core';
|
||||
import {Link as RouterLink} from '@reach/router';
|
||||
import {routes} from '../../constants';
|
||||
import Curve from '../../components/Curve';
|
||||
import Icon from '../../components/Icon';
|
||||
import Logo from '../../components/Logo';
|
||||
import demoPng from '../../images/demo.png';
|
||||
import rowExample from '../../images/row.png';
|
||||
|
||||
import headerPng from '../../images/safari-header.png';
|
||||
import regularScreenshotPng from '../../images/traditional-screenshot.png';
|
||||
import IPhoneXMockupPng from '../../images/screenshots/iphone-x-mockup.png';
|
||||
import IPhoneScreenshotPng from '../../images/screenshots/iphone-x.png';
|
||||
|
||||
import RobinLogo from '../../images/logos/robin-logo.png';
|
||||
import RemoteHQLogo from '../../images/logos/remote-hq-logo.png';
|
||||
import ReactNativeLogo from '../../images/logos/react-logo.png';
|
||||
|
||||
import '../../styles/gradient.css';
|
||||
import '../../styles/font.css';
|
||||
|
||||
@ -30,6 +35,14 @@ function color (rand) {
|
||||
'#4C84FF',
|
||||
'#e6d435',
|
||||
];
|
||||
const newer_c = [
|
||||
'#B424E6',
|
||||
'#1ACA6B',
|
||||
'#E62465',
|
||||
'#FFCD4C',
|
||||
'#4C84FF',
|
||||
'#E9519A',
|
||||
];
|
||||
return c[~~(c.length * rand)];
|
||||
}
|
||||
|
||||
@ -587,9 +600,11 @@ const PageContainer = styled('div')`
|
||||
overflow: hidden;
|
||||
background: #fcf8f3;
|
||||
position: relative;
|
||||
min-height: calc(100vh - 84px);
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
const FixedContainer = styled('div')`
|
||||
@ -601,6 +616,7 @@ const FixedContainer = styled('div')`
|
||||
`;
|
||||
|
||||
const Container = styled('div')`
|
||||
position: relative;
|
||||
background: rgb(252, 248, 243);
|
||||
width: 960px;
|
||||
margin: 0 auto;
|
||||
@ -644,12 +660,63 @@ const Header = styled('h1')`
|
||||
font-size: 72px;
|
||||
line-height: 78px;
|
||||
margin: 0 auto 12px;
|
||||
font-weight: 800;
|
||||
|
||||
font-family: medium-marketing-display-font,Georgia,Cambria,Times New Roman,Times,serif;
|
||||
font-weight: 500;
|
||||
`;
|
||||
|
||||
const ItemHeader = styled(Header)`
|
||||
position: relative;
|
||||
text-align: left;
|
||||
width: 680px;
|
||||
margin: 0;
|
||||
z-index: 2;
|
||||
font-size: 62px;
|
||||
line-height: 64px;
|
||||
margin: 0 0 12px;
|
||||
|
||||
font-family: medium-marketing-display-font,Georgia,Cambria,Times New Roman,Times,serif;
|
||||
font-weight: 500;
|
||||
`;
|
||||
|
||||
const HorizontalListItem = styled('div')`
|
||||
flex: 1;
|
||||
border-right: ${props => props.last ? '0px' : '1px'} solid rgb(206, 206, 206);
|
||||
padding: 0 32px;
|
||||
`;
|
||||
|
||||
const Quote = styled('p')`
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
&:before {
|
||||
content: open-quote;
|
||||
}
|
||||
&:after {
|
||||
content: close-quote;
|
||||
}
|
||||
`;
|
||||
|
||||
const CompanyPerson = styled('div')`
|
||||
transform: scale(0.95);
|
||||
display: flex;
|
||||
padding: 8px 0;
|
||||
margin: 0;
|
||||
img {
|
||||
display: block;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
padding: 0 16px;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
color: #37352f80;
|
||||
}
|
||||
`;
|
||||
|
||||
function getConfetti (seed) {
|
||||
const stroke = color(seed);
|
||||
const rotation = ~~(seed * 180);
|
||||
@ -755,6 +822,7 @@ function ConfettiSection () {
|
||||
}
|
||||
|
||||
const SubHeader = styled(Header)`
|
||||
hyphens: auto;
|
||||
font-size: 22px;
|
||||
line-height: 26px;
|
||||
font-weight: 600;
|
||||
@ -766,12 +834,37 @@ const SubHeader = styled(Header)`
|
||||
font-weight: 500;
|
||||
`;
|
||||
|
||||
const DemoScreenshot = styled('img')`
|
||||
max-width: 960px;
|
||||
const DemoScreenshotHeader = styled('img')`
|
||||
background: #f7f6f3;
|
||||
width: 960px;
|
||||
display: block;
|
||||
box-shadow: rgba(0, 0, 0, 0.15) 0px 10px 20px, rgb(245, 245, 245) 0px -1px 0px;
|
||||
border-radius: 4px;
|
||||
z-index: 2;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
z-index: 3;
|
||||
`;
|
||||
const DemoScreenshot = styled(DemoScreenshotHeader)`
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
`;
|
||||
|
||||
const IPhoneScreenshotContainer = styled('img')`
|
||||
position: absolute;
|
||||
bottom: -32px;
|
||||
right: -32px;
|
||||
width: 214px;
|
||||
display: block;
|
||||
background: none;
|
||||
z-index: 5;
|
||||
`;
|
||||
const IPhoneScreenshot = styled(IPhoneScreenshotContainer)`
|
||||
z-index: 4;
|
||||
transform: scale(0.88);
|
||||
bottom: -48px;
|
||||
`;
|
||||
|
||||
const SmallText = styled('p')`
|
||||
@ -786,7 +879,7 @@ const SmallText = styled('p')`
|
||||
const SmallLink = styled('a')`
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
display: inline-block;
|
||||
color: #37352f;
|
||||
z-index: 2;
|
||||
@ -903,13 +996,13 @@ export default function Scene ({loggedIn, onLogout, ...props}) {
|
||||
</FixedContainer>
|
||||
|
||||
<Container css={css`
|
||||
margin: 36px auto;
|
||||
margin: 32px auto;
|
||||
padding: 8px;
|
||||
flex-direction: column;
|
||||
`}>
|
||||
<div css={css`
|
||||
position: relative;
|
||||
margin: 0 auto 36px;
|
||||
margin: 0 auto 18px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@ -1016,7 +1109,114 @@ export default function Scene ({loggedIn, onLogout, ...props}) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<DemoScreenshot src={demoPng} />
|
||||
<div css={css`
|
||||
position: relative;
|
||||
`}>
|
||||
<DemoScreenshotHeader src={headerPng} />
|
||||
<DemoScreenshot src={regularScreenshotPng} />
|
||||
<IPhoneScreenshotContainer src={IPhoneXMockupPng} />
|
||||
<IPhoneScreenshot src={IPhoneScreenshotPng} />
|
||||
</div>
|
||||
</Container>
|
||||
|
||||
<Container css={css`
|
||||
position: relative;
|
||||
margin: 88px auto 32px;
|
||||
padding: 48px 16px;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
border-top: 1px solid rgb(221, 221, 221);
|
||||
border-bottom: 1px solid rgb(221, 221, 221);
|
||||
`}>
|
||||
<div css={css`
|
||||
position: relative;
|
||||
margin: 0 0 18px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 0;
|
||||
flex-direction: column;
|
||||
`}>
|
||||
<ItemHeader css={css`
|
||||
margin-top: 32px;
|
||||
font-size: 48px;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
`}>
|
||||
{'Hear what folks have to say'}
|
||||
</ItemHeader>
|
||||
<SubHeader css={css`
|
||||
text-align: center;
|
||||
margin-bottom: 32px;
|
||||
`}>
|
||||
{'People have been using this app for a while now and have been kind enough to share their thoughts.'}
|
||||
</SubHeader>
|
||||
<div css={css`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 32px;
|
||||
`}>
|
||||
<HorizontalListItem>
|
||||
<Quote>{`Nick is absolutely KILLING THE GAME with this app. I LOVE it!`}</Quote>
|
||||
<CompanyPerson>
|
||||
<img src={RemoteHQLogo} />
|
||||
<span>
|
||||
{'— Trevor Suarez'}<br />
|
||||
{'RemoteHQ, Software Engineer'}
|
||||
</span>
|
||||
</CompanyPerson>
|
||||
</HorizontalListItem>
|
||||
<HorizontalListItem>
|
||||
<Quote>{`So good! I love the importance sorting!`}</Quote>
|
||||
<CompanyPerson>
|
||||
<img css={css`filter: hue-rotate(222deg);`} src={ReactNativeLogo} />
|
||||
<span>
|
||||
{'— Mike Grabowski'}<br />
|
||||
{'Software Architect and Core Contributor to React Native'}
|
||||
</span>
|
||||
</CompanyPerson>
|
||||
</HorizontalListItem>
|
||||
<HorizontalListItem last>
|
||||
<Quote>{`I actually use this all the time.`}</Quote>
|
||||
<CompanyPerson>
|
||||
<img src={RobinLogo} />
|
||||
<span>
|
||||
{'— Henry Lee'}<br />
|
||||
{'Robin, Frontend Software Engineer'}
|
||||
</span>
|
||||
</CompanyPerson>
|
||||
</HorizontalListItem>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
|
||||
<Container css={css`
|
||||
margin: 88px auto 32px;
|
||||
padding: 8px;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
`}>
|
||||
<div css={css`
|
||||
position: relative;
|
||||
margin: 0 0 18px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 0;
|
||||
flex-direction: column;
|
||||
`}>
|
||||
<ItemHeader>
|
||||
{'Surface the things that matter most'}
|
||||
</ItemHeader>
|
||||
<div css={css`margin: 0 32px;`}>
|
||||
<SubHeader>
|
||||
{'Prioritize the tasks that keep you and your team most productive by organizing your notifications'}
|
||||
</SubHeader>
|
||||
</div>
|
||||
</div>
|
||||
<DemoScreenshotHeader src={headerPng} />
|
||||
<DemoScreenshot src={regularScreenshotPng} />
|
||||
</Container>
|
||||
</PageContainer>
|
||||
);
|
||||
|
@ -147,7 +147,7 @@ class NotificationsPage extends React.Component {
|
||||
}
|
||||
|
||||
state = {
|
||||
currentTime: moment().subtract(3, 'd'),
|
||||
currentTime: moment(),
|
||||
error: null,
|
||||
notificationSent: false,
|
||||
isFirstTimeUser: false,
|
||||
|
@ -24,6 +24,9 @@ const FOOTER_HEIGHT = '96px';
|
||||
const COLLAPSED_WIDTH = '72px';
|
||||
const EXPANDED_WIDTH = '286px';
|
||||
|
||||
const WIDTH_FOR_MEDIUM_SCREENS = '1100px';
|
||||
const WIDTH_FOR_SMALL_SCREENS = '750px';
|
||||
|
||||
// ========================================================================
|
||||
// START OF 'MOVE TO A UTILS FILE'
|
||||
// ========================================================================
|
||||
@ -205,6 +208,9 @@ const MenuHeaderItem = styled(Item)`
|
||||
border-right: 1px solid #292d35;
|
||||
background: #2f343e;
|
||||
z-index: 1;
|
||||
@media (max-width: ${WIDTH_FOR_SMALL_SCREENS}) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const ContentHeaderItem = styled(Item)`
|
||||
@ -212,6 +218,9 @@ const ContentHeaderItem = styled(Item)`
|
||||
width: calc(100% - ${COLLAPSED_WIDTH});
|
||||
border-bottom: 1px solid #E5E6EB;
|
||||
z-index: 1;
|
||||
@media (max-width: ${WIDTH_FOR_SMALL_SCREENS}) {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
const MenuContainerItem = styled(Item)`
|
||||
@ -219,6 +228,9 @@ const MenuContainerItem = styled(Item)`
|
||||
flex: ${({expand}) => expand ? `${EXPANDED_WIDTH} 0 0` : 1};
|
||||
height: 100%;
|
||||
transition: all 150ms ease;
|
||||
@media (max-width: ${WIDTH_FOR_SMALL_SCREENS}) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
// Faded blue: #F5F6FA
|
||||
@ -229,6 +241,11 @@ const ContentItem = styled(Item)`
|
||||
width: calc(100% - ${COLLAPSED_WIDTH});
|
||||
background: #f7f6f3;
|
||||
border-left: 1px solid #292d35;
|
||||
@media (max-width: ${WIDTH_FOR_SMALL_SCREENS}) {
|
||||
width: 100%;
|
||||
border-left: 1px solid #f7f6f3;
|
||||
border-right: 1px solid #f7f6f3;
|
||||
}
|
||||
`;
|
||||
|
||||
const CardSection = styled('div')`
|
||||
@ -236,6 +253,9 @@ const CardSection = styled('div')`
|
||||
display: inline-block;
|
||||
width: 330px;
|
||||
padding: 0 16px;
|
||||
@media (max-width: ${WIDTH_FOR_MEDIUM_SCREENS}) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const Card = styled('div')`
|
||||
@ -308,6 +328,11 @@ const NotificationsSection = styled('div')`
|
||||
padding-left: 0;
|
||||
padding-bottom: 0;
|
||||
height: auto;
|
||||
@media (max-width: ${WIDTH_FOR_MEDIUM_SCREENS}) {
|
||||
width: calc(100% - (2 * 16px));
|
||||
padding-right: 16px;
|
||||
padding-left: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const TitleSection = styled('div')`
|
||||
@ -346,6 +371,9 @@ const UnorderedList = styled('ul')`
|
||||
|
||||
const PageSelection = styled(UnorderedList)`
|
||||
border-bottom: 2px solid #e5e6eb;
|
||||
flex-wrap: nowrap;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
`;
|
||||
|
||||
const SearchField = styled('div')`
|
||||
@ -461,6 +489,9 @@ const InteractionSection = styled('ul')`
|
||||
outline: none;
|
||||
user-select: none;
|
||||
}
|
||||
@media (max-width: ${WIDTH_FOR_MEDIUM_SCREENS}) {
|
||||
width: 50px;
|
||||
}
|
||||
`;
|
||||
|
||||
const InteractionMenu = styled('div')`
|
||||
@ -498,6 +529,9 @@ const InteractionMenu = styled('div')`
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (max-width: ${WIDTH_FOR_SMALL_SCREENS}) {
|
||||
left: -240px;
|
||||
}
|
||||
`;
|
||||
|
||||
const SortingItemComponent = styled('div')`
|
||||
@ -563,6 +597,9 @@ const NotificationRow = styled(NotificationRowHeader)`
|
||||
&:active {
|
||||
background: rgb(252, 250, 248);
|
||||
};
|
||||
@media (max-width: ${WIDTH_FOR_SMALL_SCREENS}) {
|
||||
padding: 6px 2px;
|
||||
}
|
||||
`;
|
||||
|
||||
const LoadingNotificationRow = styled(NotificationRowHeader)`
|
||||
@ -617,6 +654,9 @@ const NotificationByline = styled('span')`
|
||||
margin-top: 4px;
|
||||
font-size: 12px;
|
||||
color: #8893a7cc;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
i {
|
||||
margin-right: 4px;
|
||||
font-size: 10px;
|
||||
@ -661,6 +701,9 @@ const ProfileContainer = styled('div')`
|
||||
color: #bfc5d1
|
||||
}
|
||||
}
|
||||
@media (max-width: ${WIDTH_FOR_MEDIUM_SCREENS}) {
|
||||
width: 48px;
|
||||
}
|
||||
`;
|
||||
|
||||
const ProfileName = styled('span')`
|
||||
@ -671,6 +714,9 @@ const ProfileName = styled('span')`
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: auto;
|
||||
@media (max-width: ${WIDTH_FOR_MEDIUM_SCREENS}) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const ProfilePicture = styled('img')`
|
||||
@ -1130,8 +1176,8 @@ export default function Scene ({
|
||||
});
|
||||
|
||||
readStatistics = readStatistics.map(n => parseInt(n, 10));
|
||||
const lastWeekStats = readStatistics.slice(0, 7).map(n => n || null);
|
||||
const thisWeekStats = readStatistics.slice(7).map(n => n || null);
|
||||
const lastWeekStats = readStatistics.slice(0, 7);
|
||||
const thisWeekStats = readStatistics.slice(7);
|
||||
|
||||
const percentageDeltaToday = getPercentageDelta(counts.cur, counts.prev);
|
||||
const highestRepoReadCount = Object.values(reposReadCounts).reduce((h, c) => Math.max(h, c), 0);
|
||||
@ -1170,6 +1216,7 @@ export default function Scene ({
|
||||
|
||||
return (
|
||||
<Container>
|
||||
{/* Top search & profile bar */}
|
||||
<Row css={css`
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@ -1221,6 +1268,9 @@ export default function Scene ({
|
||||
&:hover {
|
||||
opacity: 0.5;
|
||||
}
|
||||
@media (max-width: ${WIDTH_FOR_MEDIUM_SCREENS}) {
|
||||
display: none;
|
||||
}
|
||||
`}
|
||||
onClick={() => window.scrollTo(0, 0)}
|
||||
size={32}
|
||||
@ -1228,10 +1278,14 @@ export default function Scene ({
|
||||
<ProfileSection user={user} onLogout={onLogout} />
|
||||
</ContentHeaderItem>
|
||||
</Row>
|
||||
{/* Sidebar options & notifications content */}
|
||||
<Row css={css`
|
||||
height: calc(100% - ${COLLAPSED_WIDTH});
|
||||
margin-top: ${COLLAPSED_WIDTH};
|
||||
background: #2f343e;
|
||||
@media (max-width: ${WIDTH_FOR_SMALL_SCREENS}) {
|
||||
background: ${WHITE};
|
||||
}
|
||||
`}>
|
||||
<MenuContainerItem expand={menuOpen}>
|
||||
<MenuIconItem
|
||||
@ -1320,20 +1374,27 @@ export default function Scene ({
|
||||
<TitleSection>
|
||||
<Title>{titleOfMode(mode)}</Title>
|
||||
<InteractionSection>
|
||||
<li onClick={event => {
|
||||
event.stopPropagation();
|
||||
switch(notificationsPermission) {
|
||||
case 'granted':
|
||||
return setNotificationsPermission('denied');
|
||||
case 'denied':
|
||||
case 'default':
|
||||
default:
|
||||
Notification.requestPermission().then(result => {
|
||||
return setNotificationsPermission(result);
|
||||
});
|
||||
}
|
||||
setDropdownOpen(false);
|
||||
}}>
|
||||
<li
|
||||
css={css`
|
||||
@media (max-width: ${WIDTH_FOR_MEDIUM_SCREENS}) {
|
||||
display: none !important;
|
||||
}
|
||||
`}
|
||||
onClick={event => {
|
||||
event.stopPropagation();
|
||||
switch(notificationsPermission) {
|
||||
case 'granted':
|
||||
return setNotificationsPermission('denied');
|
||||
case 'denied':
|
||||
case 'default':
|
||||
default:
|
||||
Notification.requestPermission().then(result => {
|
||||
return setNotificationsPermission(result);
|
||||
});
|
||||
}
|
||||
setDropdownOpen(false);
|
||||
}}
|
||||
>
|
||||
<IconLink>
|
||||
{hasNotificationsOn ? (
|
||||
<i className="fas fa-bell"></i>
|
||||
@ -1510,12 +1571,14 @@ export default function Scene ({
|
||||
</>
|
||||
)}
|
||||
<IconLink
|
||||
css={css`@media (max-width: ${WIDTH_FOR_SMALL_SCREENS}) { display: none; }`}
|
||||
disabled={loading || isFirstPage}
|
||||
onClick={!loading && !isFirstPage ? (() => onChangePage(page - 1)) : undefined}
|
||||
>
|
||||
<i className="fas fa-chevron-left"></i>
|
||||
</IconLink>
|
||||
<IconLink
|
||||
css={css`@media (max-width: ${WIDTH_FOR_SMALL_SCREENS}) { display: none; }`}
|
||||
disabled={loading || isLastPage}
|
||||
onClick={!loading && !isLastPage ? (() => onChangePage(page + 1)) : undefined}
|
||||
>
|
||||
@ -1551,7 +1614,7 @@ export default function Scene ({
|
||||
</SortingItem>
|
||||
</NotificationCell>
|
||||
{/* Repository */}
|
||||
<NotificationCell flex={2}>
|
||||
<NotificationCell flex={2} css={css`@media (max-width: ${WIDTH_FOR_MEDIUM_SCREENS}) { display: none; }`}>
|
||||
<SortingItem
|
||||
sort={Sort.REPOSITORY}
|
||||
descending={descending}
|
||||
@ -1575,7 +1638,7 @@ export default function Scene ({
|
||||
</SortingItem>
|
||||
</NotificationCell>
|
||||
{/* Actions */}
|
||||
<NotificationCell width={70}>
|
||||
<NotificationCell width={70} css={css`@media (max-width: ${WIDTH_FOR_MEDIUM_SCREENS}) { display: none; }`}>
|
||||
<SortingItem
|
||||
sort={Sort.DATE}
|
||||
descending={descending}
|
||||
@ -1613,6 +1676,7 @@ export default function Scene ({
|
||||
</NotificationsSection>
|
||||
</ContentItem>
|
||||
</Row>
|
||||
{/* Footer links */}
|
||||
<Row css={css`
|
||||
height: calc(100% - ${COLLAPSED_WIDTH});
|
||||
background: #2f343e;
|
||||
@ -1708,7 +1772,7 @@ function NotificationCollection ({
|
||||
{notifications.map((item, xid) => (
|
||||
<AnimatedNotificationRow key={notifications.id || xid}>
|
||||
{/* Type */}
|
||||
<NotificationCell width={80}>
|
||||
<NotificationCell width={60} css={css`@media (max-width: ${WIDTH_FOR_SMALL_SCREENS}) { flex: 50px 0 0; }`}>
|
||||
{getPRIssueIcon(item.type, item.reasons)}
|
||||
</NotificationCell>
|
||||
{/* Title */}
|
||||
@ -1736,6 +1800,9 @@ function NotificationCollection ({
|
||||
css={css`
|
||||
font-weight: 500;
|
||||
color: #8994A6;
|
||||
@media (max-width: ${WIDTH_FOR_MEDIUM_SCREENS}) {
|
||||
display: none;
|
||||
}
|
||||
`}>
|
||||
{'@' + item.repository}
|
||||
</NotificationCell>
|
||||
@ -1754,6 +1821,9 @@ function NotificationCollection ({
|
||||
text-align: center;
|
||||
width: 40px;
|
||||
}
|
||||
@media (max-width: ${WIDTH_FOR_MEDIUM_SCREENS}) {
|
||||
display: none;
|
||||
}
|
||||
`}>
|
||||
<ActionItems
|
||||
item={item}
|
||||
|
@ -1,9 +1,7 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import {Status} from '../constants/status';
|
||||
// import {createMockNotifications} from '../utils/mocks';
|
||||
|
||||
// const mockNotifications = createMockNotifications(100);
|
||||
import {createMockNotifications} from '../utils/mocks';
|
||||
|
||||
export const LOCAL_STORAGE_PREFIX = '__meteorite_noti_cache__';
|
||||
export const LOCAL_STORAGE_USER_PREFIX = '__meteorite_user_cache__';
|
||||
@ -49,19 +47,9 @@ class StorageProvider extends React.Component {
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
// @TODO fix this
|
||||
// Document is out of focus, the we had notifications before this update,
|
||||
// and there was a change in notifications in the most recent update.
|
||||
// if (!document.hasFocus() &&
|
||||
// this.state.notifications.length > 0 &&
|
||||
// notifications.length !== this.state.notifications.length
|
||||
// ) {
|
||||
// this.setTitle('(1) ' + this.originalTitle);
|
||||
// } else {
|
||||
// this.setTitle(this.originalTitle);
|
||||
// }
|
||||
|
||||
this.setState({ notifications });
|
||||
|
||||
// const mockNotifications = createMockNotifications(20);
|
||||
// this.setState({ notifications: mockNotifications });
|
||||
}
|
||||
|
||||
@ -81,13 +69,21 @@ class StorageProvider extends React.Component {
|
||||
* ```
|
||||
*/
|
||||
getStat = (stat, startTime = moment(), endTime = moment().add(1, 'day')) => {
|
||||
const currentTime = moment();
|
||||
const response = [];
|
||||
|
||||
// Range reflects `[start, end)`
|
||||
for (let m = startTime.clone(); m.isBefore(endTime); m.add(1, 'day')) {
|
||||
const key = m.format('YYYY-MM-DD');
|
||||
const value = window.localStorage.getItem(`${LOCAL_STORAGE_STATISTIC_PREFIX}${key}-${stat}`);
|
||||
response.push(value || 0);
|
||||
if (value) {
|
||||
response.push(value);
|
||||
} else {
|
||||
// If the date is in the past or present, give it a value of 0. Otherwise, null.
|
||||
const fauxValue = m.clone().startOf('day').isSameOrBefore(
|
||||
currentTime.clone().startOf('day')) ? 0 : null;
|
||||
response.push(fauxValue);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|