Suppress-able broadcasts
This commit is contained in:
@ -27,7 +27,8 @@ export default class Notifications extends React.Component{
|
||||
return (
|
||||
<div className={notification.type+" notification"} key={notification.key}>
|
||||
<FontAwesome name="close" className="close-button" onClick={ e => this.props.uiActions.removeNotification(notification.key) } />
|
||||
{ notification.content }
|
||||
{notification.title ? <h4>{notification.title}</h4> : null}
|
||||
<p dangerouslySetInnerHTML={{__html: notification.content}}></p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ class DiscoverFeatured extends React.Component{
|
||||
if (playlist){
|
||||
return (
|
||||
<div className="intro">
|
||||
<Parallax image={helpers.sizedImages(playlist.images).huge} blur="25"/>
|
||||
<Parallax image={helpers.sizedImages(playlist.images).huge} blur />
|
||||
<div className="content cf">
|
||||
<Link to={global.baseURL+'playlist/'+playlist.uri}>
|
||||
<Thumbnail images={playlist.images} />
|
||||
|
||||
@ -79,7 +79,7 @@
|
||||
|
||||
&.blur {
|
||||
canvas {
|
||||
filter: blur(15px);
|
||||
@include blur();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -173,9 +173,10 @@
|
||||
|
||||
.slider.progress {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
top: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
height: 2px;
|
||||
|
||||
|
||||
@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user