From 6bae5c348c5cc80ec38cfd77c8b4917904af9261 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Wed, 5 Apr 2017 09:01:20 +1200 Subject: [PATCH] Multiple notifications are back; Customisable notification.id for rolling updates --- src/js/components/Notifications.js | 49 +++++++++++++++++++--------- src/js/helpers.js | 2 +- src/js/services/mopidy/middleware.js | 18 ++++++---- src/js/services/ui/actions.js | 7 ++-- src/js/services/ui/middleware.js | 16 +++++---- src/js/services/ui/reducer.js | 1 + src/js/views/App.js | 4 +-- src/js/views/Debug.js | 3 +- 8 files changed, 63 insertions(+), 37 deletions(-) diff --git a/src/js/components/Notifications.js b/src/js/components/Notifications.js index 37ccc332..c5651660 100755 --- a/src/js/components/Notifications.js +++ b/src/js/components/Notifications.js @@ -14,22 +14,42 @@ export default class Notifications extends React.Component{ // we only care about the last notification var notification = this.props.notifications[this.props.notifications.length-1] - if (notification.is_shortcut){ - return ( -
- -
- ) - } else { - return ( -
- this.props.uiActions.removeNotification(notification.id) } /> - { notification.content } -
- ) - } + return ( + + { + this.props.notifications.map(notification => { + switch (notification.type){ + case 'shortcut': + return ( +
+ +
+ ) + + case 'loading': + return ( +
+ this.props.uiActions.removeNotification(notification.id) } /> + { notification.content } +
+ ) + + default: + return ( +
+ this.props.uiActions.removeNotification(notification.id) } /> + { notification.content } +
+ ) + } + }) + } +
+ ) } + // do we want the loading of everything to be displayed? + // not likely... renderLoader(){ if (!this.props.load_queue){ return null @@ -59,7 +79,6 @@ export default class Notifications extends React.Component{ return (
{this.renderNotifications()} - {this.renderLoader()}
) } diff --git a/src/js/helpers.js b/src/js/helpers.js index e282c8c9..a1573e08 100755 --- a/src/js/helpers.js +++ b/src/js/helpers.js @@ -266,7 +266,7 @@ export let asURIs = function(items){ * Merge duplicated items in an array * * @param list Array the unclean array - * @param key string = the unique key (uri, tlid, etc) + * @param key string = the unique key (id, uri, tlid, etc) **/ export let mergeDuplicates = function(list, key){ var clean_list = []; diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js index c8bf7490..8d7ea6ec 100755 --- a/src/js/services/mopidy/middleware.js +++ b/src/js/services/mopidy/middleware.js @@ -237,8 +237,10 @@ const MopidyMiddleware = (function(){ } } - let process_batch = function(){ - var params = {uris: remaining_uris.splice(0,10)} + let process_batch = function(){ + store.dispatch(uiActions.createNotification('Adding '+remaining_uris.length+' URI(s)', 'loading', action.type)) + + var params = {uris: remaining_uris.splice(0,5)} if (action.next && current_track_index > -1){ params.at_position = current_track_index + uris_added + 1 } else if (action.at_position){ @@ -256,11 +258,9 @@ const MopidyMiddleware = (function(){ for (var i = 0; i < response.length; i++){ tlids.push(response[i].tlid) } - store.dispatch( pusherActions.addQueueMetadata(tlids, action.from_uri) ) + store.dispatch(pusherActions.addQueueMetadata(tlids, action.from_uri)) - console.info('Added '+tlids.length+' URI(s) to queue') - - // still more URIs? run again in 0.8s + // still more URIs? run again in 200ms // this gives our server time to handle other requests // crude, but prevents locking the server if (remaining_uris.length > 0){ @@ -268,8 +268,12 @@ const MopidyMiddleware = (function(){ function(){ process_batch() }, - 800 + 200 ) + + // all done + } else { + store.dispatch(uiActions.removeNotification(action.type)) } }) } diff --git a/src/js/services/ui/actions.js b/src/js/services/ui/actions.js index 85ba9a82..1cf31157 100755 --- a/src/js/services/ui/actions.js +++ b/src/js/services/ui/actions.js @@ -224,14 +224,13 @@ export function createBrowserNotification( data ){ } } -export function createNotification(content, type = 'default', is_shortcut = false){ +export function createNotification(content, type = 'default', id = helpers.generateGuid()){ return { type: 'CREATE_NOTIFICATION', notification: { - id: helpers.generateGuid(), + id: id, type: type, - content: content, - is_shortcut: is_shortcut + content: content } } } diff --git a/src/js/services/ui/middleware.js b/src/js/services/ui/middleware.js index fb2fae3a..2a22f600 100755 --- a/src/js/services/ui/middleware.js +++ b/src/js/services/ui/middleware.js @@ -268,13 +268,15 @@ const UIMiddleware = (function(){ case 'CREATE_NOTIFICATION': - // start a timeout to remove this notification - var timeout = setTimeout( - function(){ - store.dispatch(uiActions.removeNotification(action.notification.id)) - }, - 3000 - ) + // start a timeout to remove this (non loading) notification + if (action.notification.type != 'loading'){ + var timeout = setTimeout( + function(){ + store.dispatch(uiActions.removeNotification(action.notification.id)) + }, + (action.notification.type == 'shortcut' ? 1000 : 3000) + ) + } next(action) break diff --git a/src/js/services/ui/reducer.js b/src/js/services/ui/reducer.js index 5950a4a1..d8a8a783 100755 --- a/src/js/services/ui/reducer.js +++ b/src/js/services/ui/reducer.js @@ -711,6 +711,7 @@ export default function reducer(ui = {}, action){ case 'CREATE_NOTIFICATION': var notifications = [...ui.notifications, action.notification] + notifications = helpers.mergeDuplicates(notifications,'id') return Object.assign({}, ui, { notifications: notifications }) case 'REMOVE_NOTIFICATION': diff --git a/src/js/views/App.js b/src/js/views/App.js index 5d51ef8d..f9b6d69e 100755 --- a/src/js/views/App.js +++ b/src/js/views/App.js @@ -106,10 +106,10 @@ class App extends React.Component{ case 32: // spacebar if (this.props.play_state == 'playing'){ this.props.mopidyActions.pause() - this.props.uiActions.createNotification(null, 'pause', true) + this.props.uiActions.createNotification('pause', 'shortcut', 'shortcut') }else{ this.props.mopidyActions.play() - this.props.uiActions.createNotification(null, 'play', true) + this.props.uiActions.createNotification('play', 'shortcut', 'shortcut') } break; diff --git a/src/js/views/Debug.js b/src/js/views/Debug.js index 0692402f..3050ea7a 100755 --- a/src/js/views/Debug.js +++ b/src/js/views/Debug.js @@ -103,7 +103,8 @@ class Debug extends React.Component{
- this.props.uiActions.createNotification('Test '+Math.floor(Date.now() / 1000))}>Create notification + this.props.uiActions.createNotification('Test notification')}>Create notification + this.props.uiActions.createNotification('Test loader','loading')}>Create loader