Bringing all tracks into core index; Need to refactor loading all assets

This commit is contained in:
James Barnsley
2017-11-08 08:44:56 +13:00
parent 7739a16504
commit 5063cc095c
6 changed files with 183 additions and 65 deletions

View File

@ -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)
}
}

View File

@ -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){

View File

@ -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){

View File

@ -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

View File

@ -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;

View File

@ -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: