Bringing all tracks into core index; Need to refactor loading all assets
This commit is contained in:
@ -10,6 +10,7 @@ import * as coreActions from '../services/core/actions'
|
||||
import * as uiActions from '../services/ui/actions'
|
||||
import * as pusherActions from '../services/pusher/actions'
|
||||
import * as mopidyActions from '../services/mopidy/actions'
|
||||
import * as lastfmActions from '../services/lastfm/actions'
|
||||
import * as spotifyActions from '../services/spotify/actions'
|
||||
import TrackList from './TrackList'
|
||||
|
||||
@ -41,10 +42,10 @@ class ContextMenu extends React.Component{
|
||||
this.setState({ submenu_expanded: false })
|
||||
$('body').addClass('context-menu-open')
|
||||
|
||||
var context = this.getContext()
|
||||
var context = this.getContext(nextProps);
|
||||
|
||||
// if we're able to be in the library, run a check
|
||||
if (this.props.spotify_authorized && context.source == 'spotify'){
|
||||
if (nextProps.spotify_authorized && context.source == 'spotify'){
|
||||
switch (nextProps.menu.context){
|
||||
case 'artist':
|
||||
case 'album':
|
||||
@ -54,6 +55,14 @@ class ContextMenu extends React.Component{
|
||||
}
|
||||
}
|
||||
|
||||
// if we're able to be in the LastFM library, run a check
|
||||
if (nextProps.lastfm_authorized && context.is_track && context.items_count == 1){
|
||||
if (nextProps.menu.items[0].uri && this.props.tracks[nextProps.menu.items[0].uri] !== undefined){
|
||||
var track = this.props.tracks[nextProps.menu.items[0].uri];
|
||||
this.props.lastfmActions.getTrack(track);
|
||||
}
|
||||
}
|
||||
|
||||
// we DID have one prior, and now we don't
|
||||
} else if (this.props.menu && !nextProps.menu){
|
||||
$('body').removeClass('context-menu-open')
|
||||
@ -73,41 +82,44 @@ class ContextMenu extends React.Component{
|
||||
}
|
||||
}
|
||||
|
||||
getContext(){
|
||||
getContext(props = this.props){
|
||||
var context = {
|
||||
name: null,
|
||||
nice_name: 'Unknown'
|
||||
nice_name: 'Unknown',
|
||||
is_track: false
|
||||
}
|
||||
|
||||
if (this.props.menu && this.props.menu.context){
|
||||
context.name = this.props.menu.context
|
||||
context.nice_name = this.props.menu.context
|
||||
if (props.menu && props.menu.context){
|
||||
context.name = props.menu.context;
|
||||
context.nice_name = props.menu.context;
|
||||
|
||||
// handle ugly labels
|
||||
switch (this.props.menu.context){
|
||||
switch (props.menu.context){
|
||||
case 'playlist':
|
||||
case 'editable-playlist':
|
||||
context.nice_name = 'playlist'
|
||||
context.nice_name = 'playlist';
|
||||
break
|
||||
|
||||
case 'track':
|
||||
case 'queue-track':
|
||||
case 'playlist-track':
|
||||
case 'editable-playlist-track':
|
||||
context.nice_name = 'track'
|
||||
context.nice_name = 'track';
|
||||
context.is_track = true;
|
||||
break
|
||||
}
|
||||
|
||||
// Consider the object(s) themselves
|
||||
// We can only really accommodate the first item. The only instances where
|
||||
// there is multiple is tracklists, when they're all of the same source (except search?)
|
||||
if (this.props.menu.items && this.props.menu.items.length > 0){
|
||||
var item = this.props.menu.items[0]
|
||||
context.item = item
|
||||
context.items_count = this.props.menu.items.length
|
||||
context.source = helpers.uriSource(item.uri)
|
||||
context.type = helpers.uriType(item.uri)
|
||||
context.in_library = this.inLibrary(item)
|
||||
if (props.menu.items && props.menu.items.length > 0){
|
||||
var item = props.menu.items[0]
|
||||
context.item = item;
|
||||
context.items_count = props.menu.items.length;
|
||||
context.source = helpers.uriSource(item.uri);
|
||||
context.type = helpers.uriType(item.uri);
|
||||
context.in_library = this.inLibrary(item);
|
||||
context.is_loved = this.isLoved(item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,6 +145,23 @@ class ContextMenu extends React.Component{
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Currently the select track keys are the only details available. We need
|
||||
* the actual track object reference (including name and artists) to getTrack from LastFM
|
||||
**/
|
||||
isLoved(item = null){
|
||||
if (!item){
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.props.tracks[item.uri] === undefined){
|
||||
return false;
|
||||
}
|
||||
var track = this.props.tracks[item.uri];
|
||||
|
||||
return (track.userloved !== undefined && track.userloved == "1");
|
||||
}
|
||||
|
||||
canBeInLibrary(){
|
||||
if (!this.props.spotify_authorized){
|
||||
return false
|
||||
@ -190,6 +219,20 @@ class ContextMenu extends React.Component{
|
||||
this.props.coreActions.addTracksToPlaylist(playlist_uri, this.props.menu.uris)
|
||||
}
|
||||
|
||||
toggleLoved(e, is_loved){
|
||||
this.props.uiActions.hideContextMenu()
|
||||
if (is_loved){
|
||||
this.props.lastfmActions.unloveTrack(this.props.menu.items[0])
|
||||
} else {
|
||||
this.props.lastfmActions.loveTrack(this.props.menu.items[0])
|
||||
}
|
||||
}
|
||||
|
||||
unloveTrack(e){
|
||||
this.props.uiActions.hideContextMenu()
|
||||
this.props.lastfmActions.unloveTrack(this.props.menu.items[0])
|
||||
}
|
||||
|
||||
removeFromPlaylist(e){
|
||||
this.props.uiActions.hideContextMenu()
|
||||
this.props.coreActions.removeTracksFromPlaylist(this.props.menu.tracklist_uri, this.props.menu.indexes)
|
||||
@ -445,6 +488,29 @@ class ContextMenu extends React.Component{
|
||||
</span>
|
||||
)
|
||||
|
||||
|
||||
if (helpers.isLoading(this.props.load_queue,['lastfm_track.getInfo'])){
|
||||
var toggle_loved = (
|
||||
<span className="menu-item-wrapper">
|
||||
<a className="menu-item">
|
||||
<span className="label grey-text">
|
||||
Love track
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
)
|
||||
} else {
|
||||
var toggle_loved = (
|
||||
<span className="menu-item-wrapper">
|
||||
<a className="menu-item" onClick={e => this.toggleLoved(e, context.is_loved)}>
|
||||
<span className="label">
|
||||
{context.is_loved ? 'Unlove' : 'Love'} track
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
var go_to_artist = (
|
||||
<span className="menu-item-wrapper">
|
||||
<a className="menu-item" onClick={e => this.goToArtist(e)}>
|
||||
@ -580,6 +646,7 @@ class ContextMenu extends React.Component{
|
||||
{context.items_count == 1 ? play_queue_item : null}
|
||||
{context.items_count == 1 ? <div className="divider" /> : null}
|
||||
{add_to_playlist}
|
||||
{context.items_count == 1 ? toggle_loved : null}
|
||||
{context.source == 'spotify' && context.items_count <= 5 ? go_to_recommendations : null}
|
||||
{context.items_count == 1 ? go_to_track : null}
|
||||
<div className="divider" />
|
||||
@ -598,6 +665,7 @@ class ContextMenu extends React.Component{
|
||||
{context.source == 'spotify' && context.items_count == 1 ? start_radio : null}
|
||||
<div className="divider" />
|
||||
{add_to_playlist}
|
||||
{context.items_count == 1 ? toggle_loved : null}
|
||||
{context.source == 'spotify' && context.items_count <= 5 ? go_to_recommendations : null}
|
||||
{context.items_count == 1 ? go_to_track : null}
|
||||
<div className="divider" />
|
||||
@ -616,6 +684,7 @@ class ContextMenu extends React.Component{
|
||||
{context.source == 'spotify' && context.items_count == 1 ? start_radio : null}
|
||||
<div className="divider" />
|
||||
{add_to_playlist}
|
||||
{context.items_count == 1 ? toggle_loved : null}
|
||||
{context.source == 'spotify' && context.items_count <= 5 ? go_to_recommendations : null}
|
||||
{context.items_count == 1 ? go_to_track : null}
|
||||
<div className="divider" />
|
||||
@ -663,6 +732,7 @@ class ContextMenu extends React.Component{
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
return {
|
||||
menu: state.ui.context_menu,
|
||||
load_queue: state.ui.load_queue,
|
||||
processes: state.ui.processes,
|
||||
current_track: state.core.current_track,
|
||||
current_tracklist: state.core.current_tracklist,
|
||||
@ -675,7 +745,9 @@ const mapStateToProps = (state, ownProps) => {
|
||||
spotify_library_albums: state.spotify.library_albums,
|
||||
mopidy_library_albums: state.mopidy.library_albums,
|
||||
playlists: state.core.playlists,
|
||||
spotify_authorized: state.spotify.authorization
|
||||
tracks: state.core.tracks,
|
||||
spotify_authorized: state.spotify.authorization,
|
||||
lastfm_authorized: state.lastfm.session
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,6 +757,7 @@ const mapDispatchToProps = (dispatch) => {
|
||||
uiActions: bindActionCreators(uiActions, dispatch),
|
||||
pusherActions: bindActionCreators(pusherActions, dispatch),
|
||||
spotifyActions: bindActionCreators(spotifyActions, dispatch),
|
||||
lastfmActions: bindActionCreators(lastfmActions, dispatch),
|
||||
mopidyActions: bindActionCreators(mopidyActions, dispatch)
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ class TrackList extends React.Component{
|
||||
uris: selected_tracks_uris,
|
||||
indexes: selected_tracks_indexes
|
||||
}
|
||||
this.props.uiActions.showContextMenu(data)
|
||||
this.props.uiActions.showContextMenu(data);
|
||||
}
|
||||
|
||||
handleSelection(e,track_key){
|
||||
|
||||
@ -119,6 +119,14 @@ const CoreMiddleware = (function(){
|
||||
action.album.images = helpers.digestMopidyImages(store.getState().mopidy, action.album.images);
|
||||
}
|
||||
|
||||
// Load our tracks
|
||||
if (action.album.tracks){
|
||||
store.dispatch({
|
||||
type: 'TRACKS_LOADED',
|
||||
tracks: action.album.tracks
|
||||
});
|
||||
}
|
||||
|
||||
next(action)
|
||||
break
|
||||
|
||||
@ -129,13 +137,30 @@ const CoreMiddleware = (function(){
|
||||
if (action.albums[i].images && action.albums[i].images.length > 0){
|
||||
action.albums[i].images = helpers.digestMopidyImages(store.getState().mopidy, action.albums[i].images);
|
||||
}
|
||||
|
||||
// Load our tracks
|
||||
if (action.albums[i].tracks){
|
||||
store.dispatch({
|
||||
type: 'TRACKS_LOADED',
|
||||
tracks: action.albums[i].tracks
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'ARTIST_LOADED':
|
||||
if (action.data) ReactGA.event({ category: 'Artist', action: 'Load', label: action.artist.uri })
|
||||
if (action.data) ReactGA.event({ category: 'Artist', action: 'Load', label: action.artist.uri });
|
||||
|
||||
// Load our tracks
|
||||
if (action.artist.tracks){
|
||||
store.dispatch({
|
||||
type: 'TRACKS_LOADED',
|
||||
tracks: action.artist.tracks
|
||||
});
|
||||
}
|
||||
|
||||
next(action)
|
||||
break
|
||||
|
||||
@ -239,9 +264,17 @@ const CoreMiddleware = (function(){
|
||||
}
|
||||
}
|
||||
|
||||
// Load our tracks
|
||||
if (action.playlist.tracks){
|
||||
store.dispatch({
|
||||
type: 'TRACKS_LOADED',
|
||||
tracks: action.playlist.tracks
|
||||
});
|
||||
}
|
||||
|
||||
// proceed as usual
|
||||
action.playlist = playlist
|
||||
next(action)
|
||||
action.playlist = playlist;
|
||||
next(action);
|
||||
break
|
||||
|
||||
case 'PLAYLISTS_LOADED':
|
||||
@ -290,6 +323,49 @@ const CoreMiddleware = (function(){
|
||||
next(action)
|
||||
break
|
||||
|
||||
case 'MOPIDY_TLTRACKS':
|
||||
|
||||
var core = store.getState().core;
|
||||
var tracklist = []
|
||||
for (var i = 0; i < action.data.length; i++){
|
||||
|
||||
var tltrack = helpers.formatTracks(action.data[i]);
|
||||
|
||||
// load our metadata (if we have any for that tlid)
|
||||
if (core.queue_metadata !== undefined && core.queue_metadata['tlid_'+tltrack.tlid] !== undefined){
|
||||
var metadata = core.queue_metadata['tlid_'+tltrack.tlid]
|
||||
} else {
|
||||
var metadata = {}
|
||||
}
|
||||
|
||||
var current_tlid = null;
|
||||
if (core.current_track && core.tracks && core.tracks[core.current_track] !== undefined && core.tracks[core.current_track].tlid !== undefined){
|
||||
current_tlid = core.tracks[core.current_track].tlid;
|
||||
}
|
||||
|
||||
var track = Object.assign(
|
||||
{},
|
||||
tltrack,
|
||||
metadata,
|
||||
{
|
||||
playing: (tltrack.tlid == current_tlid)
|
||||
})
|
||||
tracklist.push(track)
|
||||
}
|
||||
|
||||
// Append to our action
|
||||
tracklist = helpers.formatTracks(tracklist);
|
||||
action.tracklist = tracklist;
|
||||
|
||||
// Load our tracks into index
|
||||
store.dispatch({
|
||||
type: 'TRACKS_LOADED',
|
||||
tracks: tracklist
|
||||
});
|
||||
|
||||
next(action);
|
||||
break
|
||||
|
||||
// Get assets from all of our providers
|
||||
case 'GET_LIBRARY_PLAYLISTS':
|
||||
if (store.getState().spotify.connected){
|
||||
|
||||
@ -12,38 +12,10 @@ export default function reducer(core = {}, action){
|
||||
**/
|
||||
|
||||
case 'MOPIDY_TLTRACKS':
|
||||
if (!action.data ) return core
|
||||
|
||||
var tracklist = []
|
||||
for (var i = 0; i < action.data.length; i++){
|
||||
|
||||
var tltrack = helpers.formatTracks(action.data[i]);
|
||||
|
||||
// load our metadata (if we have any for that tlid)
|
||||
if (core.queue_metadata !== undefined && core.queue_metadata['tlid_'+tltrack.tlid] !== undefined){
|
||||
var metadata = core.queue_metadata['tlid_'+tltrack.tlid]
|
||||
} else {
|
||||
var metadata = {}
|
||||
}
|
||||
|
||||
var current_tlid = null;
|
||||
if (core.current_track && core.tracks && core.tracks[core.current_track] !== undefined && core.tracks[core.current_track].tlid !== undefined){
|
||||
current_tlid = core.tracks[core.current_track].tlid;
|
||||
}
|
||||
|
||||
var track = Object.assign(
|
||||
{},
|
||||
tltrack,
|
||||
metadata,
|
||||
{
|
||||
playing: (tltrack.tlid == current_tlid)
|
||||
})
|
||||
tracklist.push(track)
|
||||
if (!action.tracklist){
|
||||
return core;
|
||||
}
|
||||
|
||||
tracklist = helpers.formatTracks(tracklist);
|
||||
|
||||
return Object.assign({}, core, { current_tracklist: tracklist });
|
||||
return Object.assign({}, core, { current_tracklist: action.tracklist });
|
||||
|
||||
case 'MOPIDY_CURRENTTLTRACK':
|
||||
if (!action.data) return core
|
||||
|
||||
@ -15,7 +15,10 @@ const sendRequest = (dispatch, getState, params, signed = false) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
var loader_key = helpers.generateGuid();
|
||||
dispatch(uiActions.startLoading(loader_key, 'lastfm_'+params));
|
||||
var method = params.substring(params.indexOf("method=")+7, params.length);
|
||||
method = method.substring(0, method.indexOf("&"));
|
||||
|
||||
dispatch(uiActions.startLoading(loader_key, 'lastfm_'+method));
|
||||
|
||||
var config = {
|
||||
method: 'GET',
|
||||
@ -83,8 +86,11 @@ const sendSignedRequest = (dispatch, getState, params) => {
|
||||
});
|
||||
}
|
||||
|
||||
var loader_key = helpers.generateGuid()
|
||||
dispatch(uiActions.startLoading(loader_key, 'lastfm_'+params));
|
||||
var loader_key = helpers.generateGuid();
|
||||
var method = params.substring(params.indexOf("method=")+7, params.length);
|
||||
method = method.substring(0, method.indexOf("&"));
|
||||
|
||||
dispatch(uiActions.startLoading(loader_key, 'lastfm_'+method));
|
||||
|
||||
params += "&sk="+getState().lastfm.session.key;
|
||||
|
||||
|
||||
@ -32,15 +32,6 @@ const LastfmMiddleware = (function(){
|
||||
next(action);
|
||||
break;
|
||||
|
||||
case 'MOPIDY_CURRENTTLTRACK':
|
||||
if (action.data && action.data.track){
|
||||
if (state.lastfm.session){
|
||||
store.dispatch(lastfmActions.scrobble(action.data.track));
|
||||
}
|
||||
}
|
||||
next(action);
|
||||
break;
|
||||
|
||||
|
||||
// This action is irrelevant to us, pass it on to the next middleware
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user