Metadata operational; Handle cached/local lookups that are instant; Remove old tlids
This commit is contained in:
@ -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
|
||||
|
||||
@ -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']
|
||||
)
|
||||
|
||||
|
||||
@ -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' },
|
||||
|
||||
@ -57,22 +57,35 @@ export default class Track extends React.Component{
|
||||
}
|
||||
}
|
||||
|
||||
switch (track.type){
|
||||
if (track.type == 'history'){
|
||||
|
||||
case 'history':
|
||||
var track_columns = (
|
||||
<span>
|
||||
<span className="col name">
|
||||
{ track.name ? track.name : <span className="grey-text">{track.uri}</span> }
|
||||
</span>
|
||||
<span className="col played_at">
|
||||
{ track.played_at ? <span><Dater type="ago" data={track.played_at} /> ago</span> : null }
|
||||
</span>
|
||||
var track_columns = (
|
||||
<span>
|
||||
<span className="col name">
|
||||
{ track.name ? track.name : <span className="grey-text">{track.uri}</span> }
|
||||
</span>
|
||||
)
|
||||
break;
|
||||
<span className="col played_at">
|
||||
{ track.played_at ? <span><Dater type="ago" data={track.played_at} /> ago</span> : null }
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
|
||||
} 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 = <span>{track.added_by} <span className="grey-text"> (from <Link to={global.baseURL+type+'/'+track.added_from}>{type}</Link>)</span></span>
|
||||
|
||||
} else if (track.added_from){
|
||||
var added = <span className="grey-text"> (from <Link to={global.baseURL+type+'/'+track.added_from}>{type}</Link>)</span>
|
||||
|
||||
} else if (track.added_by){
|
||||
var added = track.added_by
|
||||
|
||||
} else {
|
||||
var added = '-'
|
||||
}
|
||||
|
||||
default:
|
||||
var track_columns = (
|
||||
<span>
|
||||
<span className="col name">
|
||||
@ -84,12 +97,35 @@ export default class Track extends React.Component{
|
||||
<span className="col album">
|
||||
{album}
|
||||
</span>
|
||||
<span className="col added">
|
||||
{added}
|
||||
</span>
|
||||
<span className="col duration">
|
||||
{ track.duration_ms ? <Dater type="length" data={track.duration_ms} /> : null }
|
||||
{ track.length ? <Dater type="length" data={track.length} /> : null }
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
|
||||
} else {
|
||||
|
||||
var track_columns = (
|
||||
<span>
|
||||
<span className="col name">
|
||||
{ track.name ? track.name : <span className="grey-text">{track.uri}</span> }
|
||||
</span>
|
||||
<span className="col artists">
|
||||
{ track.artists ? <ArtistSentence artists={track.artists} /> : '-' }
|
||||
</span>
|
||||
<span className="col album">
|
||||
{album}
|
||||
</span>
|
||||
<span className="col duration">
|
||||
{ track.duration_ms ? <Dater type="length" data={track.duration_ms} /> : null }
|
||||
{ track.length ? <Dater type="length" data={track.length} /> : null }
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@ -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 (
|
||||
<div className="list-item header track">
|
||||
<span className="col name">Name</span>
|
||||
<span className="col artists">Artists</span>
|
||||
<span className="col album">Album</span>
|
||||
<span className="col added">Added by</span>
|
||||
<span className="col duration">Length</span>
|
||||
</div>
|
||||
)
|
||||
break
|
||||
|
||||
default:
|
||||
return (
|
||||
<div className="list-item header track">
|
||||
@ -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)}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 })
|
||||
|
||||
@ -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':
|
||||
|
||||
@ -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(){
|
||||
|
||||
@ -157,7 +157,7 @@ class Artist extends React.Component{
|
||||
<div className={related_artists.length > 0 ? "col w70" : "col w100"}>
|
||||
<h4 className="left-padding">Top tracks</h4>
|
||||
<div className="list-wrapper">
|
||||
{ this.props.artist.tracks ? <TrackList uris={this.props.params.uri} tracks={this.props.artist.tracks} /> : null }
|
||||
{ this.props.artist.tracks ? <TrackList uri={this.props.params.uri} tracks={this.props.artist.tracks} /> : null }
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -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(){
|
||||
|
||||
@ -82,8 +82,8 @@ class Queue extends React.Component{
|
||||
<section className="list-wrapper">
|
||||
<TrackList
|
||||
show_source_icon={true}
|
||||
context="queue-track"
|
||||
tracks={this.props.current_tracklist}
|
||||
context="queue"
|
||||
tracks={this.props.current_tracklist}
|
||||
removeTracks={ tracks => this.removeTracks( tracks ) }
|
||||
playTracks={ tracks => this.playTracks( tracks ) }
|
||||
playTrack={ track => this.playTrack( track ) }
|
||||
|
||||
@ -161,4 +161,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.queue.track-list {
|
||||
.list-item {
|
||||
.col{
|
||||
&.name,
|
||||
&.artists,
|
||||
&.album { width: 25%; }
|
||||
&.added { width: 20%; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user