Multiple notifications are back; Customisable notification.id for rolling updates

This commit is contained in:
James Barnsley
2017-04-05 09:01:20 +12:00
parent 9d56a05fc4
commit 6bae5c348c
8 changed files with 63 additions and 37 deletions

View File

@ -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 (
<div className="shortcut-notification">
<FontAwesome name={notification.type} />
</div>
)
} else {
return (
<div className={notification.type+" notification"}>
<FontAwesome name="close" className="close-button" onClick={ e => this.props.uiActions.removeNotification(notification.id) } />
{ notification.content }
</div>
)
}
return (
<span>
{
this.props.notifications.map(notification => {
switch (notification.type){
case 'shortcut':
return (
<div className="shortcut-notification" key={notification.id}>
<FontAwesome name={notification.content} />
</div>
)
case 'loading':
return (
<div className="loading notification" key={notification.id}>
<FontAwesome name="close" className="close-button" onClick={ e => this.props.uiActions.removeNotification(notification.id) } />
{ notification.content }
</div>
)
default:
return (
<div className={notification.type+" notification"} key={notification.id}>
<FontAwesome name="close" className="close-button" onClick={ e => this.props.uiActions.removeNotification(notification.id) } />
{ notification.content }
</div>
)
}
})
}
</span>
)
}
// 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 (
<div className="notifications">
{this.renderNotifications()}
{this.renderLoader()}
</div>
)
}

View File

@ -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 = [];

View File

@ -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))
}
})
}

View File

@ -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
}
}
}

View File

@ -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

View File

@ -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':

View File

@ -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;

View File

@ -103,7 +103,8 @@ class Debug extends React.Component{
<div className="field">
<div className="name"></div>
<div className="input">
<a className="button secondary" onClick={e => this.props.uiActions.createNotification('Test '+Math.floor(Date.now() / 1000))}>Create notification</a>
<a className="button secondary" onClick={e => this.props.uiActions.createNotification('Test notification')}>Create notification</a>
<a className="button secondary" onClick={e => this.props.uiActions.createNotification('Test loader','loading')}>Create loader</a>
</div>
</div>
</form>