From 02d3868d1ee012dfd2145dc6067e40963b9078b1 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Tue, 14 Feb 2017 12:13:07 +1300 Subject: [PATCH] Queue metadata endpoint --- mopidy_iris/frontend.py | 21 ++++++++++++++++++++ mopidy_iris/pusher.py | 29 ++++++++++++++++++++++++++++ src/js/components/ContextMenu.js | 6 +++--- src/js/components/TrackList.js | 2 +- src/js/services/mopidy/actions.js | 8 +++++--- src/js/services/mopidy/middleware.js | 18 +++++++++++++---- src/js/services/pusher/actions.js | 14 ++++++++++++++ src/js/services/pusher/middleware.js | 18 +++++++++++++++++ src/js/services/ui/reducer.js | 4 ++++ src/js/views/Album.js | 5 ++--- src/js/views/Artist.js | 2 +- src/js/views/Playlist.js | 2 +- 12 files changed, 113 insertions(+), 16 deletions(-) diff --git a/mopidy_iris/frontend.py b/mopidy_iris/frontend.py index d08491be..c247f985 100755 --- a/mopidy_iris/frontend.py +++ b/mopidy_iris/frontend.py @@ -27,6 +27,7 @@ class IrisFrontend(pykka.ThreadingActor, CoreListener): self.version = mopidy_iris.__version__ self.is_root = ( os.geteuid() == 0 ) self.spotify_token = False + self.queue_metadata = {} self.radio = { "enabled": 0, "seed_artists": [], @@ -190,6 +191,26 @@ class IrisFrontend(pykka.ThreadingActor, CoreListener): return self.spotify_token + # get queue metadata + def get_queue_metadata( self ): + return self.queue_metadata + + + # add queue metadata + def add_queue_metadata( self, tlids, from_uri, added_by ): + queue_metadata = self.queue_metadata + + for tlid in tlids: + item = { + 'tlid': tlid, + 'from_uri': from_uri, + 'added_by': added_by + } + queue_metadata['tlid_'+str(tlid)] = item + + return queue_metadata + + # get our config values def get_config( self ): all_config = self.config diff --git a/mopidy_iris/pusher.py b/mopidy_iris/pusher.py index 13047a14..b5fa8cbb 100755 --- a/mopidy_iris/pusher.py +++ b/mopidy_iris/pusher.py @@ -210,6 +210,35 @@ class PusherWebsocketHandler(tornado.websocket.WebSocketHandler): messageJson['request_id'], { 'connections': connectionsDetailsList } ) + + # add some queue metadata + elif messageJson['action'] == 'add_queue_metadata': + queue_metadata = self.frontend.add_queue_metadata( + messageJson['tlids'], + messageJson['from_uri'], + connections[self.connectionid]['client']['username'] + ) + + send_message( + self.connectionid, + 'response', + messageJson['request_id'], + { 'queue_metadata': queue_metadata } + ) + + # get our queue metadata (added_by, from, etc) + elif messageJson['action'] == 'get_queue_metadata': + + connectionsDetailsList = [] + for connection in connections.itervalues(): + connectionsDetailsList.append(connection['client']) + + send_message( + self.connectionid, + 'response', + messageJson['request_id'], + { 'queue_metadata': self.frontend.get_queue_metadata() } + ) # change connection's client username elif messageJson['action'] == 'set_username': diff --git a/src/js/components/ContextMenu.js b/src/js/components/ContextMenu.js index 20cb8673..3f85cf7d 100755 --- a/src/js/components/ContextMenu.js +++ b/src/js/components/ContextMenu.js @@ -55,12 +55,12 @@ class ContextMenu extends React.Component{ } playURIs(){ - this.props.mopidyActions.playURIs(this.props.menu.uris); + this.props.mopidyActions.playURIs(this.props.menu.uris, this.props.menu.tracklist_uri); this.props.uiActions.hideContextMenu(); } playURIsNext(){ - this.props.mopidyActions.enqueueURIsNext(this.props.menu.uris); + this.props.mopidyActions.enqueueURIsNext(this.props.menu.uris, this.props.menu.tracklist_uri); this.props.uiActions.hideContextMenu(); } @@ -70,7 +70,7 @@ class ContextMenu extends React.Component{ } addToQueue(){ - this.props.mopidyActions.enqueueURIs(this.props.menu.uris) + this.props.mopidyActions.enqueueURIs(this.props.menu.uris, this.props.menu.tracklist_uri) this.props.uiActions.hideContextMenu() } diff --git a/src/js/components/TrackList.js b/src/js/components/TrackList.js index f1427e87..8537aebb 100755 --- a/src/js/components/TrackList.js +++ b/src/js/components/TrackList.js @@ -122,7 +122,7 @@ class TrackList extends React.Component{ var data = { e: e, context: (this.props.context ? this.props.context : 'track'), - tracklist_uri: (this.props.tracklist_uri ? this.props.tracklist_uri : null), + tracklist_uri: (this.props.uri ? this.props.uri : null), items: selected_tracks, uris: helpers.asURIs(selected_tracks), indexes: this.tracksIndexes(selected_tracks) diff --git a/src/js/services/mopidy/actions.js b/src/js/services/mopidy/actions.js index a9a9df13..a04bb745 100755 --- a/src/js/services/mopidy/actions.js +++ b/src/js/services/mopidy/actions.js @@ -56,15 +56,17 @@ export function playURIs( uris ){ } } -export function enqueueURIsNext( uris ){ +export function enqueueURIsNext( uris, from_uri = null ){ if( typeof(uris) !== 'object' ) uris = [uris] return { type: 'MOPIDY_ENQUEUE_URIS_NEXT', - uris: uris + uris: uris, + from_uri: from_uri } } -export function enqueueURIs( uris, at_position = false ){ +// TODO: Create separate action type for this, rather than using _INSTRUCT +export function enqueueURIs( uris, from_uri = null, at_position = false ){ if( typeof(uris) !== 'object' ) uris = [uris]; var value = { uris: uris }; if( at_position ) value.at_position = at_position; diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js index 9ea7b4a8..8b980ff1 100755 --- a/src/js/services/mopidy/middleware.js +++ b/src/js/services/mopidy/middleware.js @@ -238,10 +238,13 @@ const MopidyMiddleware = (function(){ var current_track = store.getState().ui.current_track var current_tracklist = store.getState().ui.current_tracklist var current_track_index = -1 - for( var i = 0; i < current_tracklist.length; i++ ){ - if( current_tracklist[i].tlid == current_track.tlid ){ - current_track_index = i - break + + if (typeof(current_track) !== 'undefined'){ + for( var i = 0; i < current_tracklist.length; i++ ){ + if( current_tracklist[i].tlid == current_track.tlid ){ + current_track_index = i + break + } } } @@ -249,6 +252,13 @@ const MopidyMiddleware = (function(){ if( current_track_index > -1 ) at_position = current_track_index + 1 instruct( socket, store, 'tracklist.add', { uris: action.uris, at_position: at_position } ) + .then( response => { + var tlids = [] + for (var i = 0; i < response.length; i++){ + tlids.push(response[i].tlid) + } + store.dispatch( pusherActions.addQueueMetadata(tlids, action.from_uri) ) + }) break case 'MOPIDY_PLAY_URIS': diff --git a/src/js/services/pusher/actions.js b/src/js/services/pusher/actions.js index aaabbc4d..8c4440e1 100755 --- a/src/js/services/pusher/actions.js +++ b/src/js/services/pusher/actions.js @@ -75,4 +75,18 @@ export function debug( data = null ){ type: 'PUSHER_DEBUG', data: data } +} + +export function getQueueMetadata(){ + return { + type: 'PUSHER_GET_QUEUE_METADATA' + } +} + +export function addQueueMetadata( tlids = [], from_uri = null ){ + return { + type: 'PUSHER_ADD_QUEUE_METADATA', + tlids: tlids, + from_uri: from_uri + } } \ No newline at end of file diff --git a/src/js/services/pusher/middleware.js b/src/js/services/pusher/middleware.js index 6d7ebd34..f0d8dcef 100755 --- a/src/js/services/pusher/middleware.js +++ b/src/js/services/pusher/middleware.js @@ -161,6 +161,24 @@ const PusherMiddleware = (function(){ store.dispatch( uiActions.createNotification(action.data.source+': '+action.data.message,'bad') ) break; + case 'PUSHER_GET_QUEUE_METADATA': + request({ action: 'get_queue_metadata'}) + .then( + response => { + store.dispatch({ type: 'QUEUE_METADATA', queue_metadata: response.data.queue_metadata }) + } + ) + break; + + case 'PUSHER_ADD_QUEUE_METADATA': + request({ action: 'add_queue_metadata', tlids: action.tlids, from_uri: action.from_uri }) + .then( + response => { + store.dispatch({ type: 'QUEUE_METADATA', queue_metadata: response.data.queue_metadata }) + } + ) + break; + case 'START_UPGRADE': request({ action: 'upgrade' }) .then( diff --git a/src/js/services/ui/reducer.js b/src/js/services/ui/reducer.js index 960b5c1c..4bd164b9 100755 --- a/src/js/services/ui/reducer.js +++ b/src/js/services/ui/reducer.js @@ -119,6 +119,10 @@ export default function reducer(ui = {}, action){ current_track: current_track }); + case 'QUEUE_METADATA': + console.log(action) + return Object.assign({}, ui, { queue_metadata: action.queue_metadata }) + case 'RADIO': case 'START_RADIO': return Object.assign({}, ui, { seeds_resolved: false }, { radio: action.data.radio }) diff --git a/src/js/views/Album.js b/src/js/views/Album.js index 1af58527..ee1fdb8d 100755 --- a/src/js/views/Album.js +++ b/src/js/views/Album.js @@ -77,8 +77,7 @@ class Album extends React.Component{ } play(){ - var tracks_uris = helpers.asURIs( this.props.album.tracks ) - this.props.mopidyActions.playURIs( tracks_uris ) + this.props.mopidyActions.playURIs([this.props.params.uri]) } render(){ @@ -123,7 +122,7 @@ class Album extends React.Component{
- { this.props.album.tracks ? : null } + { this.props.album.tracks ? : null } this.loadMore() }/>
diff --git a/src/js/views/Artist.js b/src/js/views/Artist.js index e2e4f9b7..ab26787e 100755 --- a/src/js/views/Artist.js +++ b/src/js/views/Artist.js @@ -157,7 +157,7 @@ class Artist extends React.Component{
0 ? "col w70" : "col w100"}>

Top tracks

- { this.props.artist.tracks ? : null } + { this.props.artist.tracks ? : null }
diff --git a/src/js/views/Playlist.js b/src/js/views/Playlist.js index 2d14b75b..15e238a4 100755 --- a/src/js/views/Playlist.js +++ b/src/js/views/Playlist.js @@ -165,7 +165,7 @@ class Playlist extends React.Component{ { this.renderActions() }
- { this.props.playlist.tracks ? this.removeTracks(tracks_indexes) } reorderTracks={ (indexes, index) => this.reorderTracks(indexes, index) } /> : null } + { this.props.playlist.tracks ? this.removeTracks(tracks_indexes) } reorderTracks={ (indexes, index) => this.reorderTracks(indexes, index) } /> : null } this.loadMore() }/>