From 9a2c411e141f11e8f565d0f02af6379ebd4010d7 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Mon, 29 May 2017 16:29:49 +1200 Subject: [PATCH] Suppress-able broadcasts --- src/js/components/Notifications.js | 3 +- src/js/services/localstorage/middleware.js | 16 +++++- src/js/services/ui/actions.js | 9 +++- src/js/services/ui/middleware.js | 59 +++++++++++++++++++--- src/js/services/ui/reducer.js | 19 +++---- src/js/views/discover/DiscoverFeatured.js | 2 +- src/scss/components/_images.scss | 2 +- src/scss/components/_notifications.scss | 33 ++++++++---- src/scss/components/_player.scss | 3 +- src/scss/global/_variables.scss | 12 +++++ 10 files changed, 125 insertions(+), 33 deletions(-) diff --git a/src/js/components/Notifications.js b/src/js/components/Notifications.js index a45e2c5c..459f9126 100755 --- a/src/js/components/Notifications.js +++ b/src/js/components/Notifications.js @@ -27,7 +27,8 @@ export default class Notifications extends React.Component{ return (
this.props.uiActions.removeNotification(notification.key) } /> - { notification.content } + {notification.title ?

{notification.title}

: null} +

) } diff --git a/src/js/services/localstorage/middleware.js b/src/js/services/localstorage/middleware.js index e7b12904..e751917f 100755 --- a/src/js/services/localstorage/middleware.js +++ b/src/js/services/localstorage/middleware.js @@ -126,7 +126,21 @@ const localstorageMiddleware = (function(){ if( !ui ) ui = {}; Object.assign( ui, action.data ); localStorage.setItem('ui', JSON.stringify(ui)); - break; + break + + case 'SUPPRESS_BROADCAST': + var ui = JSON.parse(localStorage.getItem('ui')) + if (!ui) ui = {} + + var suppressed_broadcasts = (typeof(ui.suppressed_broadcasts) !== 'undefined' ? ui.suppressed_broadcasts : []) + suppressed_broadcasts.push(action.key) + + Object.assign( + ui, + { suppressed_broadcasts: suppressed_broadcasts } + ); + localStorage.setItem('ui', JSON.stringify(ui)); + break } } diff --git a/src/js/services/ui/actions.js b/src/js/services/ui/actions.js index 927820fd..2d6ef3db 100755 --- a/src/js/services/ui/actions.js +++ b/src/js/services/ui/actions.js @@ -244,13 +244,18 @@ export function createBrowserNotification( data ){ } } -export function createNotification(content, type = 'default', key = helpers.generateGuid()){ +export function createNotification(content, type = 'default', key = null, title = null, sticky = false){ + if (!key){ + key = helpers.generateGuid() + } return { type: 'CREATE_NOTIFICATION', notification: { key: key, type: type, - content: content + title: title, + content: content, + sticky: sticky } } } diff --git a/src/js/services/ui/middleware.js b/src/js/services/ui/middleware.js index 988718c2..44f3120e 100755 --- a/src/js/services/ui/middleware.js +++ b/src/js/services/ui/middleware.js @@ -302,12 +302,59 @@ const UIMiddleware = (function(){ case 'CREATE_NOTIFICATION': // start a timeout to remove this notification - var timeout = setTimeout( - function(){ - store.dispatch(uiActions.removeNotification(action.notification.key)) - }, - (action.notification.type == 'shortcut' ? 1000 : 3000) - ) + if (!action.notification.sticky){ + var timeout = setTimeout( + function(){ + store.dispatch(uiActions.removeNotification(action.notification.key)) + }, + (action.notification.type == 'shortcut' ? 1000 : 3000) + ) + } + + next(action) + break + + case 'REMOVE_NOTIFICATION': + var notifications = Object.assign([], store.getState().ui.notifications) + + function getByKey( notification ){ + return notification.key === action.key + } + var index = notifications.findIndex(getByKey) + + // Save our index for the reducer to use. Saves us from re-finding by key + action.index = index + + // If a broadcast, add to suppressed_broadcasts + if (notifications[index].type == 'broadcast'){ + store.dispatch({ + type: 'SUPPRESS_BROADCAST', + key: notifications[index].key + }) + } + + next(action) + break + + case 'BROADCASTS_LOADED': + var suppressed_broadcasts = [] + if (typeof(store.getState().ui.suppressed_broadcasts) !== 'undefined'){ + suppressed_broadcasts = store.getState().ui.suppressed_broadcasts + } + + for (var i = 0; i < action.broadcasts.length; i++){ + var broadcast = action.broadcasts[i] + + if (!suppressed_broadcasts.includes(broadcast.id)){ + store.dispatch(uiActions.createNotification( + broadcast.message, + 'broadcast', + broadcast.id, + broadcast.title, + true + )) + } + } next(action) break diff --git a/src/js/services/ui/reducer.js b/src/js/services/ui/reducer.js index 28a22d1f..54852094 100755 --- a/src/js/services/ui/reducer.js +++ b/src/js/services/ui/reducer.js @@ -4,9 +4,6 @@ import * as helpers from '../../helpers' export default function reducer(ui = {}, action){ switch (action.type) { - case 'BROADCASTS_LOADED': - return Object.assign({}, ui, {broadcasts: action.broadcasts}); - case 'LAZY_LOADING': return Object.assign({}, ui, { lazy_loading: action.start }); @@ -719,14 +716,18 @@ export default function reducer(ui = {}, action){ case 'REMOVE_NOTIFICATION': var notifications = Object.assign([], ui.notifications) - - function getByKey( notification ){ - return notification.key === action.key + + if( action.index > -1 ){ + notifications.splice(index, 1) } - var index = notifications.findIndex(getByKey) - if( index > -1 ) notifications.splice(index, 1) - return Object.assign({}, ui, { notifications: notifications }) + return Object.assign({}, ui, {notifications: notifications}) + + case 'SUPPRESS_BROADCAST': + var suppressed_broadcasts = (typeof(ui.suppressed_broadcasts) !== 'undefined' ? ui.suppressed_broadcasts : []) + suppressed_broadcasts.push(action.key) + return Object.assign({}, ui, {suppressed_broadcasts: suppressed_broadcasts}) + diff --git a/src/js/views/discover/DiscoverFeatured.js b/src/js/views/discover/DiscoverFeatured.js index 409c8223..9c4a39cb 100755 --- a/src/js/views/discover/DiscoverFeatured.js +++ b/src/js/views/discover/DiscoverFeatured.js @@ -31,7 +31,7 @@ class DiscoverFeatured extends React.Component{ if (playlist){ return (
- +
diff --git a/src/scss/components/_images.scss b/src/scss/components/_images.scss index cbaf7f41..175fbf69 100755 --- a/src/scss/components/_images.scss +++ b/src/scss/components/_images.scss @@ -79,7 +79,7 @@ &.blur { canvas { - filter: blur(15px); + @include blur(); } } } diff --git a/src/scss/components/_notifications.scss b/src/scss/components/_notifications.scss index c033533e..b07ddc49 100755 --- a/src/scss/components/_notifications.scss +++ b/src/scss/components/_notifications.scss @@ -6,23 +6,34 @@ right: 30px; z-index: 97; pointer-events: none; - width: 200px; + width: 300px; .notification { + @include fadein(); display: block; position: relative; - background: $blue; - padding: 12px 32px 12px 18px; + background: $darkest_grey; + padding: 16px 40px 16px 22px; margin: 10px 0 0 0; - color: #FFFFFF; + color: $white; pointer-events: all; + + h4 { + padding-top: 0; + } + + p a { + color: inherit; + text-decoration: none; + border-bottom: 1px dotted $black; + } .close-button { position: absolute; - top: 10px; - right: 11px; - font-size: 11px; - padding: 4px; + top: 4px; + right: 0; + font-size: 12px; + padding: 14px; cursor: pointer; opacity: 0.5; @@ -35,9 +46,9 @@ background: $green; } - &.info { + &.broadcast { background: $yellow; - color: #000000; + color: $black; } &.bad { @@ -56,7 +67,7 @@ position: absolute; display: block; content: ''; - background: rgba(0,0,0,0.35); + background: $blue; opacity: 1; animation: slideloader 1s infinite; bottom: 0; diff --git a/src/scss/components/_player.scss b/src/scss/components/_player.scss index 33e79c97..75f8b5e9 100755 --- a/src/scss/components/_player.scss +++ b/src/scss/components/_player.scss @@ -173,9 +173,10 @@ .slider.progress { position: absolute; - top: 0; + top: auto; left: 0; right: 0; + bottom: 0; margin: 0; height: 2px; diff --git a/src/scss/global/_variables.scss b/src/scss/global/_variables.scss index 21922ebc..e0f94ab4 100755 --- a/src/scss/global/_variables.scss +++ b/src/scss/global/_variables.scss @@ -100,6 +100,18 @@ $bp_shallow: 650px; animation-iteration-count: infinite; } +@keyframes fadein { + 0% { opacity: 0; } + 100% { opacity: 1; } +} + +@mixin fadein( $duration: 0.2s ){ + animation-name: fadein; + animation-duration: $duration; + animation-timing-function: linear; + animation-iteration-count: 1; +} + @mixin blur( $size: 10px ) { -webkit-filter: blur( $size ); filter: blur( $size );