From 60290db45295d99608900873072bd96445780980 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Tue, 21 Feb 2017 05:46:28 +1300 Subject: [PATCH] PUSHER_ prepends all related actions; Radio updater --- mopidy_iris/core.py | 62 +++++++++++++++++------ mopidy_iris/handlers.py | 2 +- src/js/services/pusher/actions.js | 8 +-- src/js/services/pusher/middleware.js | 72 ++++++++------------------- src/js/services/spotify/middleware.js | 3 +- src/js/services/ui/actions.js | 7 +++ src/js/services/ui/reducer.js | 10 ++-- src/js/views/Debug.js | 17 +------ src/js/views/Settings.js | 48 +++++++++++------- 9 files changed, 120 insertions(+), 109 deletions(-) diff --git a/mopidy_iris/core.py b/mopidy_iris/core.py index 14e27eaf..d83e166c 100755 --- a/mopidy_iris/core.py +++ b/mopidy_iris/core.py @@ -82,7 +82,10 @@ class IrisCore(object): def broadcast(self, data): for connection in self.connections.itervalues(): connection['connection'].write_message( json_encode(data) ) - return {} + return { + 'status': 'ok', + 'message': 'Broadcast to '+str(len(self.connections))+' connections' + } ## # Connections @@ -227,17 +230,28 @@ class IrisCore(object): self.radio = data self.radio['enabled'] = 1; - self.core.tracklist.clear() - self.core.tracklist.set_consume( True ) - self.load_more_tracks() - self.core.playback.play() - - self.broadcast({ - 'type': 'radio_started', - 'radio': self.radio - }) - - return self.get_radio({}) + uris = self.load_more_tracks() + + # no uris means we can't play radio + if not uris: + return { + 'error': 'No recommendations found' + } + + # if we got recommendations + else: + self.core.tracklist.clear() + self.core.tracklist.set_consume( True ) + self.core.tracklist.add( uris = uris ) + self.core.playback.play() + + self.broadcast({ + 'type': 'radio_started', + 'radio': self.radio + }) + + return self.get_radio({}) + def stop_radio(self, data): self.radio = { @@ -280,12 +294,28 @@ class IrisCore(object): for track in response['tracks']: uris.append( track['uri'] ) - self.core.tracklist.add( uris = uris ) + return uris except: logger.error('IrisFrontend: Failed to fetch Spotify recommendations') - self.broadcast({ - 'error': 'Failed to fetch radio recommendations' - }) + return False + + + def check_for_radio_update( self ): + tracklistLength = self.core.tracklist.length.get() + if( tracklistLength <= 5 and self.radio['enabled'] == 1 ): + + uris = self.load_more_tracks() + + if not uris: + self.broadcast({ + 'error': 'Could not fetch tracklist length', + 'source': 'check_for_radio_update' + }) + logger.warning('IrisFrontend: Could not fetch tracklist length') + + else: + self.core.tracklist.add( uris = uris ) + ## diff --git a/mopidy_iris/handlers.py b/mopidy_iris/handlers.py index 9c330ebe..9f4a84cf 100755 --- a/mopidy_iris/handlers.py +++ b/mopidy_iris/handlers.py @@ -62,7 +62,7 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler): def on_message(self, message): - + message = json_decode(message) if 'data' in message: diff --git a/src/js/services/pusher/actions.js b/src/js/services/pusher/actions.js index fa1a6a66..c24e1aa4 100755 --- a/src/js/services/pusher/actions.js +++ b/src/js/services/pusher/actions.js @@ -59,21 +59,21 @@ export function sendAuthorization( recipient_connectionid, authorization, me ){ export function startRadio( uris ){ return { - type: 'START_RADIO', + type: 'PUSHER_START_RADIO', uris: uris } } export function stopRadio(){ return { - type: 'STOP_RADIO' + type: 'PUSHER_STOP_RADIO' } } -export function debug( data = null ){ +export function debug( message = null ){ return { type: 'PUSHER_DEBUG', - data: data + message: message } } diff --git a/src/js/services/pusher/middleware.js b/src/js/services/pusher/middleware.js index 961b15d4..5dbf5a68 100755 --- a/src/js/services/pusher/middleware.js +++ b/src/js/services/pusher/middleware.js @@ -104,7 +104,7 @@ const PusherMiddleware = (function(){ return false } - response.type = 'CONFIG' + response.type = 'PUSHER_CONFIG' store.dispatch(response) if (response.config.spotify_username){ store.dispatch(spotifyActions.getUser('spotify:user:'+response.config.spotify_username)) @@ -122,7 +122,7 @@ const PusherMiddleware = (function(){ console.error(response.error) return false } - response.type = 'VERSION' + response.type = 'PUSHER_VERSION' store.dispatch(response) } ) @@ -134,7 +134,7 @@ const PusherMiddleware = (function(){ return false } - response.type = 'RADIO' + response.type = 'PUSHER_RADIO' store.dispatch(response) } ) @@ -177,7 +177,7 @@ const PusherMiddleware = (function(){ store.dispatch( uiActions.createNotification('Upgrade failed, please upgrade manually','bad') ) } - response.type = 'VERSION' + response.type = 'PUSHER_VERSION' store.dispatch(response) } ) @@ -217,15 +217,10 @@ const PusherMiddleware = (function(){ break case 'PUSHER_DEBUG': - request( action ) + request( action.message.method, action.message.data ) .then( - response => { - if (response.error){ - console.error(response.error) - return false - } - response.type = 'DEBUG' - store.dispatch(response) + response => { + store.dispatch({type: 'DEBUG', response: response}) } ) break; @@ -262,26 +257,10 @@ const PusherMiddleware = (function(){ } break - case 'START_RADIO': - request('broadcast', { - type: 'browser_notification', - title: 'Radio started', - body: store.getState().pusher.username +' started radio mode', - icon: '' - }) - .then( - response => { - if (response.data.error){ - console.error(response.data.error) - return false - } - - store.dispatch(uiActions.createNotification('Starting radio...')) - } - ) + case 'PUSHER_START_RADIO': + store.dispatch(uiActions.createNotification('Starting radio...')) var data = { - method: 'start_radio', seed_artists: [], seed_genres: [], seed_tracks: [] @@ -301,34 +280,27 @@ const PusherMiddleware = (function(){ } } - request( data ) + request( 'start_radio', data ) + .then(response => { + console.log(response) + }) break - case 'STOP_RADIO': - request('broadcast', { - type: 'browser_notification', - title: 'Radio stopped', - body: store.getState().pusher.username +' stopped radio mode', - icon: '' - }) - .then( - response => { - if (response.data.error){ - console.error(response.data.error) - return false - } - - store.dispatch(uiActions.createNotification('Stopping radio')) - } - ) + case 'PUSHER_STOP_RADIO': + store.dispatch(uiActions.createNotification('Stopping radio')) var data = { - method: 'stop_radio', seed_artists: [], seed_genres: [], seed_tracks: [] } - request( data ) + + // we don't need to wait for request, as change will be broadcast + request( 'stop_radio', data ) + break + + case 'PUSHER_BROWSER_NOTIFICATION': + store.dispatch(uiActions.createBrowserNotification(action)) break // This action is irrelevant to us, pass it on to the next middleware diff --git a/src/js/services/spotify/middleware.js b/src/js/services/spotify/middleware.js index fbbdb705..dee78940 100755 --- a/src/js/services/spotify/middleware.js +++ b/src/js/services/spotify/middleware.js @@ -87,7 +87,8 @@ const SpotifyMiddleware = (function(){ break // when radio returns - case 'RADIO': + case 'PUSHER_RADIO_STARTED': + case 'PUSHER_RADIO_CHANGED': next(action) diff --git a/src/js/services/ui/actions.js b/src/js/services/ui/actions.js index 2a947d43..3672f38f 100755 --- a/src/js/services/ui/actions.js +++ b/src/js/services/ui/actions.js @@ -215,6 +215,13 @@ export function closeModal(){ * Subtle info/tooltip messages **/ +export function createBrowserNotification( data ){ + return { + type: 'BROWSER_NOTIFICATION', + data: data + } +} + export function createNotification( content, type = 'default' ){ return { type: 'CREATE_NOTIFICATION', diff --git a/src/js/services/ui/reducer.js b/src/js/services/ui/reducer.js index 52fa489b..f03de435 100755 --- a/src/js/services/ui/reducer.js +++ b/src/js/services/ui/reducer.js @@ -13,7 +13,7 @@ export default function reducer(ui = {}, action){ case 'UI_SET': return Object.assign({}, ui, action.data) - case 'CONFIG': + case 'PUSHER_CONFIG': return Object.assign({}, ui, { config: action.config }) case 'TOGGLE_SIDEBAR': @@ -147,8 +147,10 @@ export default function reducer(ui = {}, action){ } return Object.assign({}, ui, { current_tracklist: tracklist, queue_metadata: action.queue_metadata }); - case 'RADIO': - case 'START_RADIO': + case 'PUSHER_RADIO': + case 'PUSHER_RADIO_STARTED': + case 'PUSHER_RADIO_CHANGED': + case 'PUSHER_RADIO_STOPPED': return Object.assign({}, ui, { seeds_resolved: false }, { radio: action.radio }) case 'RADIO_SEEDS_RESOLVED': @@ -371,7 +373,7 @@ export default function reducer(ui = {}, action){ case 'USER_PLAYLISTS_LOADED': var users = Object.assign([], ui.users) var playlists_uris = [] - if (users[action.key].playlists_uris) playlists_uris = users[action.key].playlists_uris + if (users[action.key] && users[action.key].playlists_uris) playlists_uris = users[action.key].playlists_uris var artist = Object.assign( {}, diff --git a/src/js/views/Debug.js b/src/js/views/Debug.js index e6497062..628b38a4 100755 --- a/src/js/views/Debug.js +++ b/src/js/views/Debug.js @@ -25,22 +25,7 @@ class Debug extends React.Component{ this.state = { mopidy_call: 'playlists.asList', mopidy_data: '{}', - pusher_data: '{}' - } - } - - componentDidMount(){ - if( this.props.connectionid ){ - var data = { - action: "broadcast", - data: { - type: 'browser_notification', - title: "Title", - body: "Test notification", - icon: "http://lorempixel.com/100/100/nature/" - } - } - this.setState({ pusher_data: JSON.stringify(data) }) + pusher_data: '{"method":"broadcast","data":{"type":"browser_notification","title":"Testing","body":"This is my message"}}' } } diff --git a/src/js/views/Settings.js b/src/js/views/Settings.js index d81e804c..bdac2956 100755 --- a/src/js/views/Settings.js +++ b/src/js/views/Settings.js @@ -56,28 +56,28 @@ class Settings extends React.Component{ } renderConnectionStatus(service){ - if( this.props[service].connected ){ + if( this.props[service.toLowerCase()].connected ){ return ( - +   - Connected + {service} ) - }else if( this.props[service].connecting ){ + }else if( this.props[service.toLowerCase()].connecting ){ return ( - +   - Connecting + {service} ) }else{ return ( - +   - Not connected + {service} ) } @@ -127,6 +127,19 @@ class Settings extends React.Component{ ) } + renderApplyButton(){ + if (this.props.mopidy.host == this.state.mopidy_host && this.props.mopidy.port == this.state.mopidy_port) return null + + return ( +
+
+
+ +
+
+ ) + } + render(){ var actions = ( @@ -142,12 +155,16 @@ class Settings extends React.Component{
-

Mopidy

+

System

this.setMopidyConfig(e)}>
Status
- { this.renderConnectionStatus('mopidy') } +
+ { this.renderConnectionStatus('Mopidy') } +    + { this.renderConnectionStatus('Pusher') } +
@@ -177,20 +194,17 @@ class Settings extends React.Component{ onChange={ e => this.setState({ mopidy_port: e.target.value })} value={ this.state.mopidy_port } />
- -
-
-
- -
+ {this.renderApplyButton()}

Spotify

Status
- { this.renderConnectionStatus('spotify') } +
+ { this.renderConnectionStatus('Spotify') } +