Merge branch 'develop'
This commit is contained in:
@ -1 +1 @@
|
||||
3.13.1
|
||||
3.14.0
|
||||
@ -101,7 +101,16 @@ class IrisCore(object):
|
||||
callback = kwargs.get('callback', None)
|
||||
|
||||
for connection in self.connections.itervalues():
|
||||
connection['connection'].write_message( json_encode(data) )
|
||||
|
||||
send_to_this_connection = True
|
||||
|
||||
# Don't send the broadcast to the origin, naturally
|
||||
if 'connection_id' in data:
|
||||
if connection['connection_id'] == data["connection_id"]:
|
||||
send_to_this_connection = False
|
||||
|
||||
if send_to_this_connection:
|
||||
connection['connection'].write_message(json_encode(data))
|
||||
|
||||
response = {
|
||||
'message': 'Broadcast to '+str(len(self.connections))+' connections'
|
||||
@ -141,6 +150,7 @@ class IrisCore(object):
|
||||
|
||||
new_connection = {
|
||||
'client': client,
|
||||
'connection_id': connection_id,
|
||||
'connection': connection
|
||||
}
|
||||
self.connections[connection_id] = new_connection
|
||||
|
||||
@ -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('stop', 'shortcut', 'shortcut');
|
||||
this.props.uiActions.createNotification({content: 'stop', type: 'shortcut', key: 'shortcut'});
|
||||
} else if (this.props.play_state == 'playing'){
|
||||
this.props.mopidyActions.pause();
|
||||
this.props.uiActions.createNotification('pause', 'shortcut', 'shortcut');
|
||||
this.props.uiActions.createNotification({content: 'pause', type: 'shortcut', key: 'shortcut'});
|
||||
} else {
|
||||
this.props.mopidyActions.play();
|
||||
this.props.uiActions.createNotification('play', 'shortcut', 'shortcut');
|
||||
this.props.uiActions.createNotification({content: 'play', type: 'shortcut', key: 'shortcut'});
|
||||
}
|
||||
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('volume-off', 'shortcut', 'shortcut');
|
||||
this.props.uiActions.createNotification({content: 'volume-off', type: 'shortcut', key: 'shortcut'});
|
||||
} 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('volume-down', 'shortcut', 'shortcut');
|
||||
this.props.uiActions.createNotification({content: 'volume-down', type: 'shortcut', key: 'shortcut'});
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -202,7 +202,7 @@ class App extends React.Component{
|
||||
if (this.props.mute){
|
||||
this.props.mopidyActions.setMute(false);
|
||||
}
|
||||
this.props.uiActions.createNotification('volume-up', 'shortcut', 'shortcut');
|
||||
this.props.uiActions.createNotification({content: 'volume-up', type: 'shortcut', key: 'shortcut'});
|
||||
} 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('volume-up', 'shortcut', 'shortcut');
|
||||
this.props.uiActions.createNotification({content: 'volume-up', type: 'shortcut', key: 'shortcut'});
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -226,20 +226,20 @@ class App extends React.Component{
|
||||
new_position = 0;;
|
||||
}
|
||||
this.props.mopidyActions.seek(new_position);
|
||||
this.props.uiActions.createNotification('fast-backward', 'shortcut', 'shortcut');
|
||||
this.props.uiActions.createNotification({content: 'fast-backward', type: 'shortcut', key: 'shortcut'});
|
||||
} else if (e.ctrlKey || e.metaKey){
|
||||
this.props.mopidyActions.previous();
|
||||
this.props.uiActions.createNotification('step-backward', 'shortcut', 'shortcut');
|
||||
this.props.uiActions.createNotification({content: 'step-backward', type: 'shortcut', key: 'shortcut'});
|
||||
}
|
||||
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('fast-forward', 'shortcut', 'shortcut');
|
||||
this.props.uiActions.createNotification({content: 'fast-forward', type: 'shortcut', key: 'shortcut'});
|
||||
} else if (e.ctrlKey || e.metaKey){
|
||||
this.props.mopidyActions.next();
|
||||
this.props.uiActions.createNotification('step-forward', 'shortcut', 'shortcut');
|
||||
this.props.uiActions.createNotification({content: 'step-forward', type: 'shortcut', key: 'shortcut'});
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@ -307,7 +307,7 @@ class ContextMenu extends React.Component{
|
||||
document.execCommand("copy");
|
||||
temp.remove();
|
||||
|
||||
this.props.uiActions.createNotification("Copied "+this.props.menu.uris.length+" URIs" )
|
||||
this.props.uiActions.createNotification({content: "Copied "+this.props.menu.uris.length+" URIs"});
|
||||
this.props.uiActions.hideContextMenu()
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ class FollowButton extends React.Component{
|
||||
}
|
||||
|
||||
if (!this.props.spotify_authorized){
|
||||
return <button className={className+' disabled'} onClick={e => this.props.uiActions.createNotification('You must authorize Spotify first','warning')}>{this.props.addText}</button>
|
||||
return <button className={className+' disabled'} onClick={e => this.props.uiActions.createNotification({content: 'You must authorize Spotify first', type: 'warning'})}>{this.props.addText}</button>
|
||||
} else if (this.props.is_following === true){
|
||||
return <button className={className+' destructive'} onClick={e => this.remove()}>{this.props.removeText}</button>
|
||||
} else {
|
||||
|
||||
@ -39,13 +39,13 @@ class LastfmAuthenticationFrame extends React.Component{
|
||||
// Only allow incoming data from our authorized authenticator proxy
|
||||
var authorization_domain = this.props.authorization_url.substring(0,this.props.authorization_url.indexOf('/',8))
|
||||
if (event.origin != authorization_domain){
|
||||
this.props.uiActions.createNotification('Authorization failed. '+event.origin+' is not the configured authorization_url.','bad')
|
||||
this.props.uiActions.createNotification({content: 'Authorization failed. '+event.origin+' is not the configured authorization_url.', type: 'bad'});
|
||||
return false
|
||||
}
|
||||
|
||||
// Bounced with an error
|
||||
if (data.error !== undefined){
|
||||
this.props.uiActions.createNotification(data.message,'bad')
|
||||
this.props.uiActions.createNotification({content: data.message, type: 'bad'});
|
||||
|
||||
// No errors? We're in!
|
||||
} else {
|
||||
@ -80,7 +80,7 @@ class LastfmAuthenticationFrame extends React.Component{
|
||||
|
||||
// Popup does not exist, so must have been blocked
|
||||
} else {
|
||||
self.props.uiActions.createNotification('Popup blocked. Please allow popups and try again.','bad')
|
||||
self.props.uiActions.createNotification({content: 'Popup blocked. Please allow popups and try again.', type: 'bad'});
|
||||
self.setState({authorizing: false})
|
||||
clearInterval(timer);
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ class FollowButton extends React.Component{
|
||||
}
|
||||
|
||||
if (!this.props.lastfm_authorized){
|
||||
return <button className={className+' disabled'} onClick={e => this.props.uiActions.createNotification('You must authorize LastFM first','warning')}>{this.props.addText}</button>
|
||||
return <button className={className+' disabled'} onClick={e => this.props.uiActions.createNotification({content: 'You must authorize LastFM first', type: 'warning'})}>{this.props.addText}</button>
|
||||
} else if (this.props.is_loved && this.props.is_loved !== "0"){
|
||||
return <button className={className+' destructive'} onClick={e => this.remove()}>{this.props.removeText}</button>
|
||||
} else {
|
||||
|
||||
@ -39,13 +39,13 @@ class SpotifyAuthenticationFrame extends React.Component{
|
||||
// Only allow incoming data from our authorized authenticator proxy
|
||||
var authorization_domain = this.props.authorization_url.substring(0,this.props.authorization_url.indexOf('/',8))
|
||||
if (event.origin != authorization_domain){
|
||||
this.props.uiActions.createNotification('Authorization failed. '+event.origin+' is not the configured authorization_url.','bad')
|
||||
this.props.uiActions.createNotification({content: 'Authorization failed. '+event.origin+' is not the configured authorization_url.', type: 'bad'});
|
||||
return false
|
||||
}
|
||||
|
||||
// Spotify bounced with an error
|
||||
if (data.error !== undefined){
|
||||
this.props.uiActions.createNotification(data.error,'bad')
|
||||
this.props.uiActions.createNotification({content: data.error, type: 'bad'});
|
||||
|
||||
// No errors? We're in!
|
||||
} else {
|
||||
@ -95,7 +95,7 @@ class SpotifyAuthenticationFrame extends React.Component{
|
||||
|
||||
// Popup does not exist, so must have been blocked
|
||||
} else {
|
||||
self.props.uiActions.createNotification('Popup blocked. Please allow popups and try again.','bad')
|
||||
self.props.uiActions.createNotification({content: 'Popup blocked. Please allow popups and try again.', type: 'bad'});
|
||||
self.setState({authorizing: false})
|
||||
clearInterval(timer);
|
||||
}
|
||||
|
||||
@ -293,7 +293,7 @@ class TrackList extends React.Component{
|
||||
var selected_tracks_indexes = helpers.arrayOf('index', selected_tracks);
|
||||
|
||||
if (selected_tracks.length <= 0){
|
||||
return this.props.uiActions.createNotification('No tracks selected', 'bad');
|
||||
return this.props.uiActions.createNotification({content: 'No tracks selected', type: 'bad'});
|
||||
}
|
||||
|
||||
// Our parent handles playing
|
||||
|
||||
@ -87,13 +87,7 @@ const CoreMiddleware = (function(){
|
||||
nonInteraction: true
|
||||
});
|
||||
|
||||
store.dispatch(uiActions.createNotification(
|
||||
message,
|
||||
'bad',
|
||||
null,
|
||||
null,
|
||||
description
|
||||
));
|
||||
store.dispatch(uiActions.createNotification({content: message, type: 'bad', description: description}));
|
||||
console.error(message, description, data);
|
||||
break;
|
||||
|
||||
@ -176,7 +170,7 @@ const CoreMiddleware = (function(){
|
||||
break
|
||||
|
||||
case 'PLAYLIST_TRACKS_ADDED':
|
||||
store.dispatch(uiActions.createNotification('Added '+action.tracks_uris.length+' tracks to playlist'))
|
||||
store.dispatch(uiActions.createNotification({content: 'Added '+action.tracks_uris.length+' tracks to playlist'}))
|
||||
switch(helpers.uriSource(action.key)){
|
||||
case 'spotify':
|
||||
store.dispatch(spotifyActions.getPlaylist(action.key))
|
||||
|
||||
@ -42,7 +42,10 @@ export function debug(call, value){
|
||||
**/
|
||||
|
||||
export function changeTrack(tlid){
|
||||
return instruct('playback.play', {tlid: tlid})
|
||||
return {
|
||||
type: 'MOPIDY_CHANGE_TRACK',
|
||||
tlid: tlid
|
||||
}
|
||||
}
|
||||
|
||||
export function playURIs(uris, from_uri = null){
|
||||
@ -85,7 +88,10 @@ export function playAlbum(uri){
|
||||
}
|
||||
|
||||
export function removeTracks(tlids){
|
||||
return instruct('tracklist.remove', {tlid: tlids})
|
||||
return {
|
||||
type: 'MOPIDY_REMOVE_TRACKS',
|
||||
tlids: tlids
|
||||
}
|
||||
}
|
||||
|
||||
export function reorderTracklist(indexes, insert_before){
|
||||
@ -104,7 +110,9 @@ export function clearTracklist(){
|
||||
}
|
||||
|
||||
export function play(){
|
||||
return instruct('playback.play')
|
||||
return {
|
||||
type: 'MOPIDY_TRIGGER_PLAY'
|
||||
}
|
||||
}
|
||||
|
||||
export function pause(){
|
||||
|
||||
@ -274,26 +274,69 @@ const MopidyMiddleware = (function(){
|
||||
* General playback
|
||||
**/
|
||||
|
||||
case 'MOPIDY_NEXT':
|
||||
case 'MOPIDY_TRIGGER_PLAY':
|
||||
instruct(socket, store, 'playback.play');
|
||||
var data = {
|
||||
type: 'browser_notification',
|
||||
title: 'Track skipped',
|
||||
body: store.getState().pusher.username +' skipped this track',
|
||||
type: 'notification',
|
||||
notification_type: 'info',
|
||||
content: store.getState().pusher.username +(store.getState().mopidy.play_state == 'paused' ? ' resumed' : ' started')+' playback',
|
||||
icon: (store.getState().core.current_track ? helpers.getTrackIcon(store.getState().core.current_track, store.getState().core) : false)
|
||||
}
|
||||
store.dispatch(pusherActions.deliverBroadcast(data) )
|
||||
store.dispatch(pusherActions.deliverBroadcast(data));
|
||||
break
|
||||
|
||||
case 'MOPIDY_PAUSE':
|
||||
var data = {
|
||||
type: 'notification',
|
||||
notification_type: 'info',
|
||||
content: store.getState().pusher.username +' paused playback',
|
||||
icon: (store.getState().core.current_track ? helpers.getTrackIcon(store.getState().core.current_track, store.getState().core) : false)
|
||||
}
|
||||
store.dispatch(pusherActions.deliverBroadcast(data));
|
||||
break
|
||||
|
||||
case 'MOPIDY_NEXT':
|
||||
var data = {
|
||||
type: 'notification',
|
||||
notification_type: 'info',
|
||||
content: store.getState().pusher.username +' skipped <em>'+store.getState().core.current_track.name+'</em>',
|
||||
icon: (store.getState().core.current_track ? helpers.getTrackIcon(store.getState().core.current_track, store.getState().core) : false)
|
||||
}
|
||||
store.dispatch(pusherActions.deliverBroadcast(data));
|
||||
break
|
||||
|
||||
case 'MOPIDY_STOP':
|
||||
var data = {
|
||||
type: 'browser_notification',
|
||||
title: 'Playback stopped',
|
||||
body: store.getState().pusher.username +' stopped playback',
|
||||
type: 'notification',
|
||||
notification_type: 'info',
|
||||
content: store.getState().pusher.username +' stopped playback',
|
||||
icon: (store.getState().core.current_track ? helpers.getTrackIcon(store.getState().core.current_track, store.getState().core) : false)
|
||||
}
|
||||
store.dispatch(pusherActions.deliverBroadcast(data) )
|
||||
store.dispatch(pusherActions.deliverBroadcast(data));
|
||||
break
|
||||
|
||||
case 'MOPIDY_CHANGE_TRACK':
|
||||
instruct(socket, store, 'playback.play', {tlid: action.tlid});
|
||||
|
||||
var broadcast_data = {
|
||||
type: 'notification',
|
||||
notification_type: 'info',
|
||||
content: store.getState().pusher.username +' changed track'
|
||||
}
|
||||
store.dispatch(pusherActions.deliverBroadcast(broadcast_data));
|
||||
break;
|
||||
|
||||
case 'MOPIDY_REMOVE_TRACKS':
|
||||
instruct(socket, store, 'tracklist.remove', {tlid: action.tlids});
|
||||
|
||||
var broadcast_data = {
|
||||
type: 'notification',
|
||||
notification_type: 'info',
|
||||
content: store.getState().pusher.username +' removed '+action.tlids.length+' tracks'
|
||||
}
|
||||
store.dispatch(pusherActions.deliverBroadcast(broadcast_data));
|
||||
break;
|
||||
|
||||
case 'MOPIDY_PLAY_PLAYLIST':
|
||||
|
||||
// Clear tracklist (if set)
|
||||
@ -326,7 +369,7 @@ const MopidyMiddleware = (function(){
|
||||
.then(
|
||||
response => {
|
||||
if (response.tracks === undefined){
|
||||
store.dispatch(uiActions.createNotification('Failed to load playlist tracks','bad'))
|
||||
store.dispatch(uiActions.createNotification({content: 'Failed to load playlist tracks', type: 'bad'}));
|
||||
} else {
|
||||
var tracks_uris = helpers.arrayOf('uri',response.tracks)
|
||||
store.dispatch(mopidyActions.playURIs(tracks_uris, action.uri))
|
||||
@ -344,10 +387,18 @@ const MopidyMiddleware = (function(){
|
||||
case 'MOPIDY_ENQUEUE_URIS':
|
||||
|
||||
if (!action.uris || action.uris.length <= 0){
|
||||
this.props.uiActions.createNotification("No URIs to enqueue","warning");
|
||||
this.props.uiActions.createNotification({content: "No URIs to enqueue", type: "warning"});
|
||||
break;
|
||||
}
|
||||
|
||||
var broadcast_data = {
|
||||
type: 'notification',
|
||||
notification_type: 'info',
|
||||
content: store.getState().pusher.username +' is adding '+action.uris.length+' URIs to queue',
|
||||
icon: (store.getState().core.current_track ? helpers.getTrackIcon(store.getState().core.current_track, store.getState().core) : false)
|
||||
}
|
||||
store.dispatch(pusherActions.deliverBroadcast(broadcast_data));
|
||||
|
||||
// split into batches
|
||||
var uris = Object.assign([], action.uris)
|
||||
var batches = []
|
||||
@ -477,7 +528,7 @@ const MopidyMiddleware = (function(){
|
||||
case 'MOPIDY_PLAY_URIS':
|
||||
|
||||
if (!action.uris || action.uris.length <= 0){
|
||||
this.props.uiActions.createNotification("No URIs to play","warning");
|
||||
this.props.uiActions.createNotification({content: "No URIs to play", type: "warning"});
|
||||
break;
|
||||
}
|
||||
|
||||
@ -491,7 +542,7 @@ const MopidyMiddleware = (function(){
|
||||
store.dispatch(mopidyActions.clearTracklist());
|
||||
}
|
||||
|
||||
var first_uri = action.uris[0]
|
||||
var first_uri = action.uris[0];
|
||||
|
||||
// add our first track
|
||||
instruct(socket, store, 'tracklist.add', { uri: first_uri, at_position: 0 })
|
||||
@ -576,7 +627,7 @@ const MopidyMiddleware = (function(){
|
||||
var uri_scheme = uri_schemes.shift();
|
||||
|
||||
if (uri_schemes_total <= 0){
|
||||
store.dispatch(uiActions.createNotification('No sources selected', 'warning'));
|
||||
store.dispatch(uiActions.createNotification({content: 'No sources selected', type: 'warning'}));
|
||||
} else {
|
||||
store.dispatch(uiActions.startProcess(
|
||||
'MOPIDY_GET_SEARCH_RESULTS_PROCESSOR',
|
||||
@ -1287,7 +1338,7 @@ const MopidyMiddleware = (function(){
|
||||
hashHistory.push(global.baseURL+'playlist/'+encodeURIComponent(response.uri));
|
||||
}
|
||||
|
||||
store.dispatch(uiActions.createNotification('Saved'));
|
||||
store.dispatch(uiActions.createNotification({content: 'Saved'}));
|
||||
})
|
||||
});
|
||||
break
|
||||
@ -1337,7 +1388,7 @@ const MopidyMiddleware = (function(){
|
||||
case 'MOPIDY_CREATE_PLAYLIST':
|
||||
instruct(socket, store, 'playlists.create', { name: action.name, uri_scheme: action.scheme })
|
||||
.then(response => {
|
||||
store.dispatch(uiActions.createNotification('Created playlist'))
|
||||
store.dispatch(uiActions.createNotification({content: 'Created playlist'}))
|
||||
|
||||
store.dispatch({
|
||||
type: 'PLAYLIST_LOADED',
|
||||
@ -1356,7 +1407,7 @@ const MopidyMiddleware = (function(){
|
||||
case 'MOPIDY_DELETE_PLAYLIST':
|
||||
instruct(socket, store, 'playlists.delete', { uri: action.uri })
|
||||
.then(response => {
|
||||
store.dispatch(uiActions.createNotification('Deleted playlist'))
|
||||
store.dispatch(uiActions.createNotification({content: 'Deleted playlist'}))
|
||||
store.dispatch({
|
||||
type: 'MOPIDY_LIBRARY_PLAYLIST_DELETED',
|
||||
key: action.uri
|
||||
|
||||
@ -228,7 +228,7 @@ const PusherMiddleware = (function(){
|
||||
request(store, 'deliver_message', action.data)
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch(uiActions.createNotification('Message delivered') )
|
||||
store.dispatch(uiActions.createNotification({content: 'Message delivered'}));
|
||||
},
|
||||
error => {
|
||||
store.dispatch(coreActions.handleException(
|
||||
@ -278,9 +278,9 @@ const PusherMiddleware = (function(){
|
||||
}
|
||||
|
||||
if (response.upgrade_successful){
|
||||
store.dispatch(uiActions.createNotification('Upgrade complete') )
|
||||
store.dispatch(uiActions.createNotification({content: 'Upgrade complete'}));
|
||||
} else {
|
||||
store.dispatch(uiActions.createNotification('Upgrade failed, please upgrade manually','bad') )
|
||||
store.dispatch(uiActions.createNotification({content: 'Upgrade failed, please upgrade manually', type: 'bad'}));
|
||||
}
|
||||
|
||||
response.type = 'PUSHER_VERSION'
|
||||
@ -381,7 +381,7 @@ const PusherMiddleware = (function(){
|
||||
response => {
|
||||
store.dispatch(uiActions.processFinished('PUSHER_RADIO_PROCESS'));
|
||||
if (response.status == 0){
|
||||
store.dispatch(uiActions.createNotification(response.message, 'bad'));
|
||||
store.dispatch(uiActions.createNotification({content: response.message, type: 'bad'}));
|
||||
}
|
||||
},
|
||||
error => {
|
||||
@ -395,8 +395,8 @@ const PusherMiddleware = (function(){
|
||||
break
|
||||
|
||||
case 'PUSHER_STOP_RADIO':
|
||||
store.dispatch(uiActions.createNotification('Stopping radio'))
|
||||
ReactGA.event({ category: 'Pusher', action: 'Stop radio' })
|
||||
store.dispatch(uiActions.createNotification({content: 'Stopping radio'}));
|
||||
ReactGA.event({ category: 'Pusher', action: 'Stop radio' });
|
||||
|
||||
var data = {
|
||||
seed_artists: [],
|
||||
@ -420,6 +420,16 @@ const PusherMiddleware = (function(){
|
||||
store.dispatch(uiActions.createBrowserNotification(action))
|
||||
break
|
||||
|
||||
case 'PUSHER_NOTIFICATION':
|
||||
var data = Object.assign(
|
||||
{},
|
||||
action, {
|
||||
type: action.notification_type
|
||||
}
|
||||
);
|
||||
store.dispatch(uiActions.createNotification(data));
|
||||
break
|
||||
|
||||
case 'PUSHER_RESTART':
|
||||
// Hard reload. This doesn't strictly clear the cache, but our compiler's
|
||||
// cache buster should handle that
|
||||
@ -430,7 +440,7 @@ const PusherMiddleware = (function(){
|
||||
ReactGA.event({ category: 'Pusher', action: 'Version', label: action.version.current })
|
||||
|
||||
if (action.version.upgrade_available){
|
||||
store.dispatch(uiActions.createNotification('Version '+action.version.latest+' is available. See settings to upgrade.' ) )
|
||||
store.dispatch(uiActions.createNotification({content: 'Version '+action.version.latest+' is available. See settings to upgrade.'}));
|
||||
}
|
||||
next(action )
|
||||
break
|
||||
|
||||
@ -1456,7 +1456,7 @@ export function createPlaylist(name, description, is_public, is_collaborative){
|
||||
uris: [response.uri]
|
||||
})
|
||||
|
||||
dispatch(uiActions.createNotification('Created playlist'))
|
||||
dispatch(uiActions.createNotification({content: 'Created playlist'}));
|
||||
},
|
||||
error => {
|
||||
dispatch(coreActions.handleException(
|
||||
@ -1491,7 +1491,7 @@ export function savePlaylist(uri, name, description, is_public, is_collaborative
|
||||
description: description
|
||||
}
|
||||
})
|
||||
dispatch(uiActions.createNotification('Saved'))
|
||||
dispatch(uiActions.createNotification({content: 'Saved'}));
|
||||
},
|
||||
error => {
|
||||
dispatch(coreActions.handleException(
|
||||
|
||||
@ -175,20 +175,22 @@ export function createBrowserNotification(data){
|
||||
}
|
||||
}
|
||||
|
||||
export function createNotification(content, type = 'default', key = null, title = null, description = null, sticky = false){
|
||||
if (!key){
|
||||
key = helpers.generateGuid()
|
||||
}
|
||||
// content, type = 'default', key = null, title = null, description = null, sticky = false
|
||||
|
||||
export function createNotification(data){
|
||||
return {
|
||||
type: 'CREATE_NOTIFICATION',
|
||||
notification: {
|
||||
key: key,
|
||||
type: type,
|
||||
title: title,
|
||||
description: description,
|
||||
content: content,
|
||||
sticky: sticky
|
||||
}
|
||||
notification: Object.assign(
|
||||
{
|
||||
key: helpers.generateGuid(),
|
||||
type: 'default',
|
||||
title: null,
|
||||
content: null,
|
||||
description: null,
|
||||
sticky: false
|
||||
},
|
||||
data
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,6 @@ const UIMiddleware = (function(){
|
||||
* The actual middleware inteceptor
|
||||
**/
|
||||
return store => next => action => {
|
||||
|
||||
switch(action.type){
|
||||
|
||||
case 'MOPIDY_STATE':
|
||||
@ -117,14 +116,14 @@ const UIMiddleware = (function(){
|
||||
|
||||
if (!suppressed_broadcasts.includes(broadcast.key)){
|
||||
if (broadcast.message){
|
||||
store.dispatch(uiActions.createNotification(
|
||||
broadcast.message,
|
||||
'broadcast',
|
||||
(broadcast.key ? broadcast.key : null),
|
||||
(broadcast.title ? broadcast.title : null),
|
||||
null,
|
||||
true
|
||||
))
|
||||
var data = {
|
||||
key: (broadcast.key ? broadcast.key : null),
|
||||
title: (broadcast.title ? broadcast.title : null),
|
||||
content: broadcast.message,
|
||||
type: 'broadcast',
|
||||
sticky: true
|
||||
}
|
||||
store.dispatch(uiActions.createNotification(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ 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 notification')}>Create notification</a>
|
||||
<a className="button secondary" onClick={e => this.props.uiActions.createNotification({content: 'Test notification'})}>Create notification</a>
|
||||
<a className="button secondary" onClick={e => this.props.uiActions.startProcess('test_process', 'Test process', {total: 100, remaining: 17})}>Start process</a>
|
||||
<a className="button secondary" onClick={e => this.props.uiActions.processFinished('test_process')}>Stop process</a>
|
||||
</div>
|
||||
@ -169,7 +169,8 @@ class Debug extends React.Component{
|
||||
<option value='{"method":"get_connections"}'>Get connections</option>
|
||||
<option value='{"method":"get_radio"}'>Get radio</option>
|
||||
<option value='{"method":"get_queue_metadata"}'>Get queue metadata</option>
|
||||
<option value='{"method":"broadcast","data":{"type":"browser_notification","title":"Testing","body":"This is my message"}}'>Broadcast to all clients</option>
|
||||
<option value='{"method":"broadcast","data":{"type":"browser_notification","title":"Testing","body":"This is my message"}}'>Broadcast to all clients (browser)</option>
|
||||
<option value='{"method":"broadcast","data":{"type":"notification","notification_type":"info","title":"Testing","content":"This is my message"}}'>Broadcast to all clients (notification)</option>
|
||||
<option value='{"method":"deliver_message","data":{"to":"CONNECTION_ID_HERE","message":{"type":"browser_notification","title":"Testing","body":"This is my message"}}}'>Broadcast to one client</option>
|
||||
<option value='{"method":"set_username","data":{"connection_id":"CONNECTION_ID_HERE","username":"NewUsername"}}'>Change username</option>
|
||||
<option value='{"method":"refresh_spotify_token"}'>Refresh Spotify token</option>
|
||||
|
||||
@ -54,12 +54,15 @@
|
||||
background: $green;
|
||||
}
|
||||
|
||||
&.broadcast,
|
||||
&.info {
|
||||
&.broadcast {
|
||||
background: $yellow;
|
||||
color: $black;
|
||||
}
|
||||
|
||||
&.info {
|
||||
background: $grey;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background: $orange;
|
||||
}
|
||||
|
||||
@ -105,8 +105,14 @@ $bp_shallow: 650px;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(5px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin fadein($duration: 0.2s){
|
||||
|
||||
Reference in New Issue
Block a user