From ef2f8732959beaa3f3b7442733f1e05675f93ca5 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Tue, 14 Feb 2017 20:24:35 +1300 Subject: [PATCH] Metadata operational; Handle cached/local lookups that are instant; Remove old tlids --- mopidy_iris/frontend.py | 4 +- mopidy_iris/pusher.py | 2 +- src/js/components/ContextMenu.js | 2 +- src/js/components/Track.js | 62 ++++++++++++++++++++++------ src/js/components/TrackList.js | 15 ++++++- src/js/services/mopidy/actions.js | 16 ++++--- src/js/services/mopidy/middleware.js | 28 +++++++++++-- src/js/services/pusher/middleware.js | 8 +++- src/js/services/ui/reducer.js | 21 +++++++--- src/js/views/Album.js | 2 +- src/js/views/Artist.js | 2 +- src/js/views/Playlist.js | 2 +- src/js/views/Queue.js | 4 +- src/scss/components/_lists.scss | 11 +++++ 14 files changed, 138 insertions(+), 41 deletions(-) diff --git a/mopidy_iris/frontend.py b/mopidy_iris/frontend.py index c247f985..5198383c 100755 --- a/mopidy_iris/frontend.py +++ b/mopidy_iris/frontend.py @@ -197,13 +197,13 @@ class IrisFrontend(pykka.ThreadingActor, CoreListener): # add queue metadata - def add_queue_metadata( self, tlids, from_uri, added_by ): + def add_queue_metadata( self, tlids, added_from, added_by ): queue_metadata = self.queue_metadata for tlid in tlids: item = { 'tlid': tlid, - 'from_uri': from_uri, + 'added_from': added_from, 'added_by': added_by } queue_metadata['tlid_'+str(tlid)] = item diff --git a/mopidy_iris/pusher.py b/mopidy_iris/pusher.py index b5fa8cbb..e868051b 100755 --- a/mopidy_iris/pusher.py +++ b/mopidy_iris/pusher.py @@ -215,7 +215,7 @@ class PusherWebsocketHandler(tornado.websocket.WebSocketHandler): elif messageJson['action'] == 'add_queue_metadata': queue_metadata = self.frontend.add_queue_metadata( messageJson['tlids'], - messageJson['from_uri'], + messageJson['added_from'], connections[self.connectionid]['client']['username'] ) diff --git a/src/js/components/ContextMenu.js b/src/js/components/ContextMenu.js index 3f85cf7d..207b019f 100755 --- a/src/js/components/ContextMenu.js +++ b/src/js/components/ContextMenu.js @@ -158,7 +158,7 @@ class ContextMenu extends React.Component{ ] break - case 'queue-track': + case 'queue': var items = [ { handleClick: 'playQueueItem', label: 'Play' }, { handleClick: 'addToPlaylist', label: 'Add to playlist' }, diff --git a/src/js/components/Track.js b/src/js/components/Track.js index f0dc358f..cbcd8515 100755 --- a/src/js/components/Track.js +++ b/src/js/components/Track.js @@ -57,22 +57,35 @@ export default class Track extends React.Component{ } } - switch (track.type){ + if (track.type == 'history'){ - case 'history': - var track_columns = ( - - - { track.name ? track.name : {track.uri} } - - - { track.played_at ? ago : null } - + var track_columns = ( + + + { track.name ? track.name : {track.uri} } - ) - break; + + { track.played_at ? ago : null } + + + ) + + } else if (this.props.context == 'queue'){ + var type = (track.added_from ? helpers.uriType(track.added_from) : null) + + if (track.added_from && track.added_by){ + var added = {track.added_by} (from {type}) + + } else if (track.added_from){ + var added = (from {type}) + + } else if (track.added_by){ + var added = track.added_by + + } else { + var added = '-' + } - default: var track_columns = ( @@ -84,12 +97,35 @@ export default class Track extends React.Component{ {album} + + {added} + { track.duration_ms ? : null } { track.length ? : null } ) + + } else { + + var track_columns = ( + + + { track.name ? track.name : {track.uri} } + + + { track.artists ? : '-' } + + + {album} + + + { track.duration_ms ? : null } + { track.length ? : null } + + + ) } return ( diff --git a/src/js/components/TrackList.js b/src/js/components/TrackList.js index 8537aebb..96c0e99b 100755 --- a/src/js/components/TrackList.js +++ b/src/js/components/TrackList.js @@ -240,7 +240,7 @@ class TrackList extends React.Component{ for( var i = 0; i < tracks.length; i++ ){ uris.push( tracks[i].uri ) } - return this.props.mopidyActions.playURIs( uris ) + return this.props.mopidyActions.playURIs( uris, this.props.uri ) } removeTracks(){ @@ -269,6 +269,18 @@ class TrackList extends React.Component{ ) break + case 'queue': + return ( +
+ Name + Artists + Album + Added by + Length +
+ ) + break + default: return (
@@ -295,6 +307,7 @@ class TrackList extends React.Component{ show_source_icon={ this.props.show_source_icon } key={track.key} track={track} + context={this.props.context} handleDoubleClick={ e => self.handleDoubleClick(e, index)} handleMouseUp={ e => self.handleMouseUp(e, index)} handleMouseDown={ e => self.handleMouseDown(e, index)} diff --git a/src/js/services/mopidy/actions.js b/src/js/services/mopidy/actions.js index a04bb745..6bc37c39 100755 --- a/src/js/services/mopidy/actions.js +++ b/src/js/services/mopidy/actions.js @@ -49,10 +49,11 @@ export function changeTrack( tlid ){ } } -export function playURIs( uris ){ +export function playURIs( uris, from_uri = null ){ return { type: 'MOPIDY_PLAY_URIS', - uris: uris + uris: uris, + from_uri: from_uri } } @@ -65,15 +66,12 @@ export function enqueueURIsNext( uris, from_uri = null ){ } } -// 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; return { - type: 'MOPIDY_INSTRUCT', - call: 'tracklist.add', - value: value + type: 'MOPIDY_ENQUEUE_URIS', + uris: uris, + at_position: at_position, + from_uri: from_uri } } diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js index 8b980ff1..23b4b0dd 100755 --- a/src/js/services/mopidy/middleware.js +++ b/src/js/services/mopidy/middleware.js @@ -233,6 +233,22 @@ const MopidyMiddleware = (function(){ }) break; + case 'MOPIDY_ENQUEUE_URIS': + var value = { uris: action.uris } + if (action.at_position){ + value.at_position = action.at_position + } + + instruct( socket, store, 'tracklist.add', value ) + .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_ENQUEUE_URIS_NEXT': var current_track = store.getState().ui.current_track @@ -273,16 +289,22 @@ const MopidyMiddleware = (function(){ .then( response => { if( !response || response.length <= 0 ){ - store.dispatch( uiActions.createNotification('Could not add URI(s) to tracklist', 'error') ) + store.dispatch( uiActions.createNotification('Failed to load URI(s)', 'bad') ) }else{ // play it - store.dispatch( mopidyActions.changeTrack( response[0].tlid ) ); + store.dispatch( mopidyActions.changeTrack( response[0].tlid ) ); + + var tlids = [] + for (var i = 0; i < response.length; i++){ + tlids.push(response[i].tlid) + } + store.dispatch( pusherActions.addQueueMetadata(tlids, action.from_uri) ) } // add the rest of our uris (if any) action.uris.shift(); if( action.uris.length > 0 ){ - store.dispatch( mopidyActions.enqueueURIs( action.uris, 1 ) ) + store.dispatch( mopidyActions.enqueueURIs( action.uris, action.from_uri, 1 ) ) } }) break; diff --git a/src/js/services/pusher/middleware.js b/src/js/services/pusher/middleware.js index f0d8dcef..2705c7e3 100755 --- a/src/js/services/pusher/middleware.js +++ b/src/js/services/pusher/middleware.js @@ -154,6 +154,12 @@ const PusherMiddleware = (function(){ store.dispatch({ type: 'RADIO', data: response.data }) } ) + request({ action: 'get_queue_metadata'}) + .then( + response => { + store.dispatch({ type: 'QUEUE_METADATA', queue_metadata: response.data.queue_metadata }) + } + ) return next(action); break; @@ -171,7 +177,7 @@ const PusherMiddleware = (function(){ break; case 'PUSHER_ADD_QUEUE_METADATA': - request({ action: 'add_queue_metadata', tlids: action.tlids, from_uri: action.from_uri }) + request({ action: 'add_queue_metadata', tlids: action.tlids, added_from: action.from_uri }) .then( response => { store.dispatch({ type: 'QUEUE_METADATA', queue_metadata: response.data.queue_metadata }) diff --git a/src/js/services/ui/reducer.js b/src/js/services/ui/reducer.js index 4bd164b9..9ad0f8dd 100755 --- a/src/js/services/ui/reducer.js +++ b/src/js/services/ui/reducer.js @@ -81,12 +81,23 @@ export default function reducer(ui = {}, action){ var tracklist = [] for( var i = 0; i < action.data.length; i++ ){ + + var tltrack = action.data[i] + + // load our metadata (if we have any for that tlid) + if (typeof(ui.queue_metadata) !== 'undefined' && typeof(ui.queue_metadata['tlid_'+tltrack.tlid]) !== 'undefined'){ + var metadata = ui.queue_metadata['tlid_'+tltrack.tlid] + } else { + var metadata = {} + } + var track = Object.assign( {}, - action.data[i].track, + tltrack.track, + metadata, { - tlid: action.data[i].tlid, - playing: ( ui.current_track && action.data[i].tlid == ui.current_track.tlid ) + tlid: tltrack.tlid, + playing: ( ui.current_track && tltrack.tlid == ui.current_track.tlid ) }) tracklist.push( track ) } @@ -120,8 +131,8 @@ export default function reducer(ui = {}, action){ }); case 'QUEUE_METADATA': - console.log(action) - return Object.assign({}, ui, { queue_metadata: action.queue_metadata }) + console.log(action); + return Object.assign({}, ui, { queue_metadata: action.queue_metadata }); case 'RADIO': case 'START_RADIO': diff --git a/src/js/views/Album.js b/src/js/views/Album.js index ee1fdb8d..0cb6ce98 100755 --- a/src/js/views/Album.js +++ b/src/js/views/Album.js @@ -77,7 +77,7 @@ class Album extends React.Component{ } play(){ - this.props.mopidyActions.playURIs([this.props.params.uri]) + this.props.mopidyActions.playURIs([this.props.params.uri], this.props.params.uri) } render(){ diff --git a/src/js/views/Artist.js b/src/js/views/Artist.js index ab26787e..6b396b86 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 15e238a4..3fabbb0d 100755 --- a/src/js/views/Playlist.js +++ b/src/js/views/Playlist.js @@ -59,7 +59,7 @@ class Playlist extends React.Component{ play(){ ReactGA.event({ category: 'Playlist', action: 'Play', label: this.props.playlist.uri }) - this.props.mopidyActions.playURIs([this.props.playlist.uri]) + this.props.mopidyActions.playURIs([this.props.playlist.uri], this.props.params.uri) } follow(){ diff --git a/src/js/views/Queue.js b/src/js/views/Queue.js index e5b56ccc..e74b7f03 100755 --- a/src/js/views/Queue.js +++ b/src/js/views/Queue.js @@ -82,8 +82,8 @@ class Queue extends React.Component{
this.removeTracks( tracks ) } playTracks={ tracks => this.playTracks( tracks ) } playTrack={ track => this.playTrack( track ) } diff --git a/src/scss/components/_lists.scss b/src/scss/components/_lists.scss index 85d0fc7d..4469e5f7 100755 --- a/src/scss/components/_lists.scss +++ b/src/scss/components/_lists.scss @@ -161,4 +161,15 @@ } } } + + .queue.track-list { + .list-item { + .col{ + &.name, + &.artists, + &.album { width: 25%; } + &.added { width: 20%; } + } + } + } } \ No newline at end of file