Notifications have customisable duration and CSS animation in-and-out
This commit is contained in:
@ -157,13 +157,13 @@ class App extends React.Component{
|
||||
case 32: // spacebar
|
||||
if (e.ctrlKey || e.metaKey){
|
||||
this.props.mopidyActions.stop();
|
||||
this.props.uiActions.createNotification({content: 'stop', type: 'shortcut', key: 'shortcut'});
|
||||
this.props.uiActions.createNotification({content: 'stop', type: 'shortcut', key: 'shortcut', duration: 1});
|
||||
} else if (this.props.play_state == 'playing'){
|
||||
this.props.mopidyActions.pause();
|
||||
this.props.uiActions.createNotification({content: 'pause', type: 'shortcut', key: 'shortcut'});
|
||||
this.props.uiActions.createNotification({content: 'pause', type: 'shortcut', key: 'shortcut', duration: 1});
|
||||
} else {
|
||||
this.props.mopidyActions.play();
|
||||
this.props.uiActions.createNotification({content: 'play', type: 'shortcut', key: 'shortcut'});
|
||||
this.props.uiActions.createNotification({content: 'play', type: 'shortcut', key: 'shortcut', duration: 1});
|
||||
}
|
||||
break;
|
||||
|
||||
@ -179,7 +179,7 @@ class App extends React.Component{
|
||||
case 40: // down
|
||||
if ((e.ctrlKey || e.metaKey) && e.shiftKey){
|
||||
this.props.mopidyActions.setMute(true);
|
||||
this.props.uiActions.createNotification({content: 'volume-off', type: 'shortcut', key: 'shortcut'});
|
||||
this.props.uiActions.createNotification({content: 'volume-off', type: 'shortcut', key: 'shortcut', duration: 1});
|
||||
} else if (e.ctrlKey){
|
||||
var volume = this.props.volume;
|
||||
if (volume !== 'false'){
|
||||
@ -191,7 +191,7 @@ class App extends React.Component{
|
||||
if (this.props.mute){
|
||||
this.props.mopidyActions.setMute(false);
|
||||
}
|
||||
this.props.uiActions.createNotification({content: 'volume-down', type: 'shortcut', key: 'shortcut'});
|
||||
this.props.uiActions.createNotification({content: 'volume-down', type: 'shortcut', key: 'shortcut', duration: 1});
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -202,7 +202,7 @@ class App extends React.Component{
|
||||
if (this.props.mute){
|
||||
this.props.mopidyActions.setMute(false);
|
||||
}
|
||||
this.props.uiActions.createNotification({content: 'volume-up', type: 'shortcut', key: 'shortcut'});
|
||||
this.props.uiActions.createNotification({content: 'volume-up', type: 'shortcut', key: 'shortcut', duration: 1});
|
||||
} else if (e.ctrlKey || e.metaKey){
|
||||
var volume = this.props.volume
|
||||
if (volume !== 'false'){
|
||||
@ -214,7 +214,7 @@ class App extends React.Component{
|
||||
if (this.props.mute){
|
||||
this.props.mopidyActions.setMute(false);
|
||||
}
|
||||
this.props.uiActions.createNotification({content: 'volume-up', type: 'shortcut', key: 'shortcut'});
|
||||
this.props.uiActions.createNotification({content: 'volume-up', type: 'shortcut', key: 'shortcut', duration: 1});
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -226,20 +226,20 @@ class App extends React.Component{
|
||||
new_position = 0;;
|
||||
}
|
||||
this.props.mopidyActions.seek(new_position);
|
||||
this.props.uiActions.createNotification({content: 'fast-backward', type: 'shortcut', key: 'shortcut'});
|
||||
this.props.uiActions.createNotification({content: 'fast-backward', type: 'shortcut', key: 'shortcut', duration: 1});
|
||||
} else if (e.ctrlKey || e.metaKey){
|
||||
this.props.mopidyActions.previous();
|
||||
this.props.uiActions.createNotification({content: 'step-backward', type: 'shortcut', key: 'shortcut'});
|
||||
this.props.uiActions.createNotification({content: 'step-backward', type: 'shortcut', key: 'shortcut', duration: 1});
|
||||
}
|
||||
break;
|
||||
|
||||
case 39: // right
|
||||
if ((e.ctrlKey || e.metaKey) && e.shiftKey){
|
||||
this.props.mopidyActions.seek(this.props.play_time_position + 30000);
|
||||
this.props.uiActions.createNotification({content: 'fast-forward', type: 'shortcut', key: 'shortcut'});
|
||||
this.props.uiActions.createNotification({content: 'fast-forward', type: 'shortcut', key: 'shortcut', duration: 1});
|
||||
} else if (e.ctrlKey || e.metaKey){
|
||||
this.props.mopidyActions.next();
|
||||
this.props.uiActions.createNotification({content: 'step-forward', type: 'shortcut', key: 'shortcut'});
|
||||
this.props.uiActions.createNotification({content: 'step-forward', type: 'shortcut', key: 'shortcut', duration: 1});
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@ -18,14 +18,14 @@ export default class Notifications extends React.Component{
|
||||
switch (notification.type){
|
||||
case 'shortcut':
|
||||
return (
|
||||
<div className="shortcut-notification" key={notification.key}>
|
||||
<div className="notification shortcut-notification" key={notification.key} data-duration={notification.duration}>
|
||||
<FontAwesome name={notification.content} />
|
||||
</div>
|
||||
)
|
||||
|
||||
default:
|
||||
return (
|
||||
<div className={notification.type+" notification"} key={notification.key} data-key={notification.key}>
|
||||
<div className={notification.type+" notification"} key={notification.key} data-key={notification.key} data-duration={notification.duration}>
|
||||
<FontAwesome name="close" className="close-button" onClick={ e => this.props.uiActions.removeNotification(notification.key) } />
|
||||
{notification.title ? <h4>{notification.title}</h4> : null}
|
||||
<p className="content" dangerouslySetInnerHTML={{__html: notification.content}}></p>
|
||||
|
||||
@ -183,6 +183,7 @@ export function createNotification(data){
|
||||
notification: Object.assign(
|
||||
{
|
||||
key: helpers.generateGuid(),
|
||||
duration: 3,
|
||||
type: 'default',
|
||||
title: null,
|
||||
content: null,
|
||||
|
||||
@ -76,7 +76,7 @@ const UIMiddleware = (function(){
|
||||
function(){
|
||||
store.dispatch(uiActions.removeNotification(action.notification.key))
|
||||
},
|
||||
(action.notification.type == 'shortcut' ? 1000 : 3000)
|
||||
action.notification.duration * 1000
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -9,15 +9,22 @@
|
||||
width: 300px;
|
||||
|
||||
.notification {
|
||||
@include fadein();
|
||||
display: block;
|
||||
position: relative;
|
||||
background: $blue;
|
||||
padding: 16px 40px 16px 22px;
|
||||
margin: 10px 0 0 0;
|
||||
color: $white;
|
||||
pointer-events: all;
|
||||
pointer-events: all;
|
||||
border-radius: 3px;
|
||||
|
||||
&[data-duration="1"]{
|
||||
@include fadeinout(1s);
|
||||
}
|
||||
|
||||
&[data-duration="3"]{
|
||||
@include fadeinout(3s);
|
||||
}
|
||||
|
||||
h4 {
|
||||
padding-top: 0;
|
||||
|
||||
@ -104,19 +104,45 @@ $bp_shallow: 650px;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(5px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
@mixin fadein($duration: 0.2s){
|
||||
@keyframes fadein {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(5px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
|
||||
animation-name: fadein;
|
||||
animation-duration: $duration;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: 1;
|
||||
}
|
||||
|
||||
@mixin fadein($duration: 0.2s){
|
||||
animation-name: fadein;
|
||||
@mixin fadeinout($duration: 3s){
|
||||
@keyframes fadeinout {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(5px);
|
||||
}
|
||||
6% {
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
94% {
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translateY(5px);
|
||||
}
|
||||
}
|
||||
|
||||
animation-name: fadeinout;
|
||||
animation-duration: $duration;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: 1;
|
||||
|
||||
Reference in New Issue
Block a user