diff --git a/README.md b/README.md index ffe2105..5d1d43f 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,13 @@ It's actually pretty simple - we use GitHub's notifications API to get your noti Using this information, we're able to give a score of importantce to each thread based on the history of reasons we saw coming in. For example, a pull request that is assigned to you, has your review requested, and has 30 comments on it, will be scored much higher than an issue you opened up and received a single comment of someone saying "nice" on it. -We're also able to hook into web notifications to alert you when you get a GitHub notification if you'd want - something like this is totally opt-in. +We're also able to hook into desktop notifications to alert you when you get a GitHub notification if you'd want - something like this is totally opt-in. Some key features include: - Scores your notifications based on their importance, so we can surface the most critical updates at the top of your queue. - Provides you with quick context for why you're receiving each notification. - - Allows you to opt in for web notifications whenever you recieve important update to help notify you right away. + - Allows you to opt in for desktop notifications whenever you recieve important update to help notify you right away. - Protects you from useless spammy notifications that you don't care about. - Let's you focus in on specific types of notifications that matter to you, like when your review is requested for a pull request or you were assigned an issue. - Unlocks dope statistics that help you understand how you interact with notifications on a daily basis. diff --git a/src/images/iconCircle.png b/src/images/iconCircle.png new file mode 100644 index 0000000..9df9473 Binary files /dev/null and b/src/images/iconCircle.png differ diff --git a/src/images/logoSquare.png b/src/images/logoSquare.png new file mode 100644 index 0000000..583065c Binary files /dev/null and b/src/images/logoSquare.png differ diff --git a/src/images/row.png b/src/images/row.png index 5cd8858..ea6ca02 100644 Binary files a/src/images/row.png and b/src/images/row.png differ diff --git a/src/images/screenshot.png b/src/images/screenshot.png index d0d539b..3f06d78 100644 Binary files a/src/images/screenshot.png and b/src/images/screenshot.png differ diff --git a/src/pages/Home/Scene.js b/src/pages/Home/Scene.js index ec0f4d3..bca45c7 100644 --- a/src/pages/Home/Scene.js +++ b/src/pages/Home/Scene.js @@ -713,7 +713,7 @@ export default function Scene ({loggedIn, onLogout, ...props}) { -

Allows you to opt in for web notifications whenever you recieve important update to help notify you right away.

+

Allows you to opt in for desktop notifications whenever you recieve important update to help notify you right away.

diff --git a/src/pages/Notifications/Scene.js b/src/pages/Notifications/Scene.js index d141a20..cc53d3e 100644 --- a/src/pages/Notifications/Scene.js +++ b/src/pages/Notifications/Scene.js @@ -485,53 +485,164 @@ const SmallLink = styled('a')({ } }); -const BarGraph = styled('div')({ +const BarGraphDiv = styled('div')({ position: 'relative', height: 100, ':after': { - content: `"Triaged notifications compared to last week"`, + content: `"Notifications Read"`, position: 'absolute', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - textAlign: 'center', - fontSize: 10, - width: '100%', - bottom: -30, + textAlign: 'left', + fontSize: 16, + top: -67, + left: -23, fontWeight: 500 } }); +const FauxGridLine = styled('div')({ + position: 'absolute', + width: '100%', + height: 1, + background: '#f3f3f3', +}, ({offsetY, tick, showDecimals}) => ({ + bottom: offsetY, + ':after': tick !== false ? { + content: showDecimals + ? `"${tick.toFixed(2).replace('.00', '')}"` + : `"${Math.round(tick)}"`, + position: 'absolute', + top: '-6px', + left: '-30px', + width: '20px', + textAlign: 'right', + } : {} +})); + +const Legend = styled('div')({ + position: 'absolute', + textAlign: 'left', + top: -35, + left: -23, +}); + +const LegendItem = styled('div')({ + position: 'relative', + display: 'inline-block', + fontSize: 12, + marginRight: 15, +}, ({color}) => ({ + ':before': { + content: '" "', + background: color, + display: 'inline-block', + height: 12, + width: 12, + borderRadius: 2, + marginRight: 5, + verticalAlign: 'middle' + } +})); + +function BarGraph ({children, numLines, max, ...props}) { + const height = 100; + const gapSize = height / (numLines - 1); + const yAxisTickOffset = gapSize / 100 * max; + // Only show decimals if we have to, e.g. the steps are under 1. + const showDecimals = yAxisTickOffset * numLines < 2; + return ( + + + Last week + This week + + {new Array(numLines).fill(0).map((_, i) => ( + 0 || i === 0 ? ( + i % 2 === 0 ? i * yAxisTickOffset : false + ) : ( + false + )} + /> + ))} + {children} + + ); +} + +const Separator = styled('div')({ + position: 'relative', + background: '#f3f3f3', + width: '100%', + height: 1, + margin: '30px 0' +}); + const BarContainer = styled('div')({ position: 'absolute', display: 'flex', flexDirection: 'row', - justifyContent: 'space-around', + justifyContent: 'space-evenly', width: '100%', height: 100, alignItems: 'flex-end', -}, ({opacity}) => ({ +}, ({opacity, hide}) => ({ 'div': { - opacity: opacity === undefined ? 1 : opacity + background: opacity ? '#f2f9ff' : undefined, + opacity: hide ? 0 : 1 } })); const stripe_size = 3; const Bar = styled('div')({ position: 'relative', - width: 20, + width: 30, minHeight: 5, background: '#00d19a', borderRadius: 4, -}, ({height, active, color = '#00d19a', visible = true}) => ({ +}, ({height, active, label, visible = true, bottomTick}) => ({ height, background: !visible ? 'none' - : active - ? `repeating-linear-gradient(45deg, ${color}, ${color} ${stripe_size}px, ${color}55 ${stripe_size}px, ${color}55 ${stripe_size * 2}px)` - : color, + : active && false + ? `repeating-linear-gradient(45deg, #28abf0, #28abf0 ${stripe_size}px, #28abf055 ${stripe_size}px, #28abf055 ${stripe_size * 2}px)` + : '#28abf0', + ':after': label ? { + content: `"${label}"`, + position: 'absolute', + left: '-20px', + width: '70px', + textAlign: 'center', + bottom: '-25px', + color: '#3f464c', + } : {}, + ':before': bottomTick ? { + content: '" "', + position: 'absolute', + background: '#f3f3f3', + width: '1px', + height: '8px', + bottom: '-8px', + left: '14px', + } : {}, })); +const PageCount = styled('div')({ + fontSize: 12, + margin: '12px auto', + width: '100%', + textAlign: 'center', + color: 'rgb(32, 33, 36)' +}); + +const NotificationIconWrapper = styled('div')({ + background: '#22303f', + borderRadius: 4, + transform: 'scale(.65)' +}); + const EnhancedBar = withTooltip(Bar); const EnhancedTab = withTooltip(Tab); const EnhancedNavTab = withTooltip(NavTab); @@ -541,16 +652,22 @@ const EnhancedIconHot = withTooltip(Icon.Hot); const EnhancedIconTimer = withTooltip(Icon.Timer); const EnhancedIconConvo = withTooltip(Icon.Convo); -function getPRIssueIcon (type, reasons) { - const grow = 1.0; +// @TODO if GitHub ever fixes their API, we can use `reasons` to know when +// a PR/Issue merges/closes/etc. +function getPRIssueIcon (type, _reasons) { + const scale = 1.0; switch (type) { case 'PullRequest': return ( - + + + ); case 'Issue': return ( - + + + ); default: return null; @@ -600,18 +717,19 @@ export default function Scene ({ ? Icon.NotificationsOn : Icon.NotificationsOff; - // console.log('notifications', notifications) - // console.log('isFirstTimeUser', isFirstTimeUser) - // console.log('notificationsPermission', notificationsPermission) - if (isFirstTimeUser && notifications.length > 10) { // probably prompt to mark all as read to start out since they prob don't use notifs } stagedStatistics = stagedStatistics.map(n => parseInt(n, 10)); + const highestStagedCount = stagedStatistics.reduce((n, m) => Math.max(n, m), 0); - const lastWeekStats = stagedStatistics.slice(0, 7); - const thisWeekStats = stagedStatistics.slice(7); + let lastWeekStats = stagedStatistics.slice(0, 7); + let thisWeekStats = stagedStatistics.slice(7); + + // Trim off the weekends. + lastWeekStats = lastWeekStats.slice(1, -1); + thisWeekStats = thisWeekStats.slice(1, -1); return (
@@ -756,21 +874,23 @@ export default function Scene ({ )} commented +
- + {/* Last week's statistics */} - + {lastWeekStats.map((dayStats, i) => ( ))} @@ -779,35 +899,39 @@ export default function Scene ({ {thisWeekStats.map((dayStats, i) => ( = i} + label={i % 2 === 0 ? getWeekday(i + 1) : null} + bottomTick={true} + // color={getColorFromFilter(activeFilter)} + active={currentTime.day() === i + 1} + height={(dayStats / (highestStagedCount * 1.15)) * 100} + visible={currentTime.day() >= i + 1} /> ))} {/* Wrapper for tooltips */} - + {/* {thisWeekStats.map((dayStats, i) => ( ))} - + */}
+
@@ -853,8 +977,8 @@ export default function Scene ({ - {n.badges.map(badge => { + {activeStatus === Status.QUEUED && n.badges.map(badge => { switch (badge) { case Badges.HOT: // lots of `reasons` within short time frame @@ -1143,6 +1267,7 @@ export default function Scene ({ )} + {!loading && Page {page} out of {lastPage}}