Tracks and Queue overhaul

This commit is contained in:
James Barnsley
2017-11-10 15:56:01 +13:00
parent e2dbbac98b
commit 93cbbaa7fa
15 changed files with 256 additions and 281 deletions

5
src/js/bootstrap.js vendored
View File

@ -32,8 +32,9 @@ let reducers = combineReducers({
// TODO: Look at using propTypes in the component for these falsy initial states
var initialState = {
core: {
current_tracklist: [],
current_tltrack: false,
queue: [],
queue_metadata: {},
current_track_uri: null,
albums: {},
artists: {},
playlists: {},

View File

@ -45,7 +45,7 @@ class LastfmAuthenticationFrame extends React.Component{
// Bounced with an error
if (data.error !== undefined){
this.props.uiActions.createNotification(data.error,'bad')
this.props.uiActions.createNotification(data.message,'bad')
// No errors? We're in!
} else {

View File

@ -145,7 +145,7 @@ class Modal extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
current_track: (state.core.current_track !== undefined && state.core.tracks !== undefined && state.core.tracks[state.core.current_track] !== undefined ? state.core.tracks[state.core.current_track] : null),
current_track: (state.core.tracks[state.core.current_track_uri] !== undefined ? state.core.tracks[state.core.current_track_uri] : null),
uri_schemes: (state.mopidy.uri_schemes ? state.mopidy.uri_schemes : []),
search_uri_schemes: (state.ui.search_uri_schemes ? state.ui.search_uri_schemes : []),
volume: state.mopidy.volume,

View File

@ -135,7 +135,7 @@ class PlaybackControls extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
current_track: (state.core.current_track !== undefined && state.core.tracks !== undefined && state.core.tracks[state.core.current_track] !== undefined ? state.core.tracks[state.core.current_track] : null),
current_track: (state.core.tracks[state.core.current_track_uri] !== undefined ? state.core.tracks[state.core.current_track_uri] : null),
radio_enabled: (state.ui.radio && state.ui.radio.enabled ? true : false),
play_state: state.mopidy.play_state,
time_position: state.mopidy.time_position,

View File

@ -81,8 +81,8 @@ export function set(data){
**/
export function reorderPlaylistTracks(uri, indexes, insert_before, snapshot_id = false){
var range = helpers.createRange(indexes );
switch(helpers.uriSource(uri )){
var range = helpers.createRange(indexes);
switch(helpers.uriSource(uri)){
case 'spotify':
return {

View File

@ -186,81 +186,6 @@ const CoreMiddleware = (function(){
next(action)
break
case 'MOPIDY_CURRENTTLTRACK':
if (action.data && action.data.track){
helpers.setWindowTitle(action.data.track, store.getState().mopidy.play_state);
// make sure our images use mopidy host:port
if (action.data.track.album && action.data.track.album.images && action.data.track.album.images.length > 0){
var images = Object.assign([], action.data.track.album.images)
for (var i = 0; i < images.length; i++){
if (typeof(images[i]) === 'string' && images[i].startsWith('/images/')){
images[i] = '//'+store.getState().mopidy.host+':'+store.getState().mopidy.port+images[i]
}
}
action.data.track.album.images = images
}
}
var current_tracklist = []
Object.assign(current_tracklist, core.current_tracklist)
for (var i = 0; i < current_tracklist.length; i++){
Object.assign(
current_tracklist[i],
{ playing: (current_tracklist[i].tlid == action.data.tlid) }
)
}
// Update action
action.current_tracklist = current_tracklist;
action.current_track = action.data.track.uri;
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){
@ -295,8 +220,115 @@ const CoreMiddleware = (function(){
break
case 'RESTART':
location.reload()
break
location.reload();
break;
/**
* Playlist manipulation
**/
case 'PLAYLIST_KEY_UPDATED':
var playlists = Object.assign({}, core.playlists);
if (playlists[action.key] === undefined){
dispatch(coreActions.handleException("Cannot change key of playlist not in index"));
}
// Delete our old playlist by key, and add by new key
var playlist = Object.assign({}, playlists[action.key]);
delete playlists[action.key];
playlists[action.new_key] = playlist;
store.dispatch({
type: 'UPDATE_PLAYLISTS_INDEX',
playlists: playlists
});
break;
case 'PLAYLIST_TRACKS_REORDERED':
var playlists = Object.assign({}, core.playlists);
var playlist = Object.assign({}, playlists[action.key]);
var tracks_uris = Object.assign([], playlist.tracks_uris);
// handle insert_before offset if we're moving BENEATH where we're slicing tracks
var insert_before = action.insert_before
if (insert_before > action.range_start){
insert_before = insert_before - action.range_length;
}
// cut our moved tracks into a new array
var tracks_to_move = tracks_uris.splice(action.range_start, action.range_length)
tracks_to_move.reverse()
for (i = 0; i < tracks_to_move.length; i++){
tracks_uris.splice(insert_before, 0, tracks_to_move[i])
}
var snapshot_id = null;
if (action.snapshot_id){
snapshot_id = action.snapshot_id;
}
// Update our playlist
playlist.tracks_uris = tracks_uris;
playlist.snapshot_id = snapshot_id;
// Trigger normal playlist updating
store.dispatch({
type: 'PLAYLISTS_LOADED',
playlists: [playlist]
});
break;
case 'PLAYLIST_TRACKS_REMOVED':
var playlists = Object.assign({}, core.playlists);
var playlist = Object.assign({}, playlists[action.key]);
var tracks_uris = Object.assign([], playlist.tracks_uris);
var indexes = action.tracks_indexes.reverse()
for(var i = 0; i < indexes.length; i++){
tracks_uris.splice(indexes[i], 1);
}
var snapshot_id = null;
if (action.snapshot_id){
snapshot_id = action.snapshot_id;
}
// Update our playlist
playlist.tracks_uris = tracks_uris;
playlist.snapshot_id = snapshot_id;
// Trigger normal playlist updating
store.dispatch({
type: 'PLAYLISTS_LOADED',
playlists: [playlist]
});
break;
/**
* Queue and playback info
**/
case 'CURRENT_TRACK_LOADED':
store.dispatch({
type: 'TRACKS_LOADED',
tracks: [action.current_track]
});
next(action);
break;
case 'QUEUE_LOADED':
store.dispatch({
type: 'TRACKS_LOADED',
tracks: action.tracks
});
action.tracks_uris = helpers.arrayOf('uri',action.tracks);
next(action);
break;
/**
@ -309,8 +341,7 @@ const CoreMiddleware = (function(){
store.dispatch({
type: 'TRACKS_LOADED',
tracks: [action.track]
})
next(action);
});
break;
// Array wrapper for ALBUMS_LOADED
@ -319,7 +350,6 @@ const CoreMiddleware = (function(){
type: 'ALBUMS_LOADED',
albums: [action.album]
});
next(action);
break;
// Array wrapper for ARTISTS_LOADED
@ -328,7 +358,6 @@ const CoreMiddleware = (function(){
type: 'ARTISTS_LOADED',
artists: [action.artist]
});
next(action);
break;
// Array wrapper for PLAYLISTS_LOADED
@ -337,7 +366,6 @@ const CoreMiddleware = (function(){
type: 'PLAYLISTS_LOADED',
playlists: [action.playlist]
});
next(action);
break;
// Array wrapper for USERS_LOADED
@ -346,7 +374,6 @@ const CoreMiddleware = (function(){
type: 'USERS_LOADED',
users: [action.user]
});
next(action);
break;
case 'TRACKS_LOADED':
@ -361,6 +388,7 @@ const CoreMiddleware = (function(){
if (track.album && track.album.images && track.album.images.length > 0){
track.album.images = helpers.digestMopidyImages(store.getState().mopidy, track.album.images);
track.images = track.album.images;
}
tracks[track.uri] = track;
@ -523,7 +551,7 @@ const CoreMiddleware = (function(){
user = Object.assign({}, users[user.uri], user);
}
users[action.key] = user;
users[user.uri] = user;
}
// Update index
@ -542,6 +570,7 @@ const CoreMiddleware = (function(){
**/
case 'LOADED_MORE':
console.log(action);
var parent_type_plural = action.parent_type+'s';
var parent_index = Object.assign({}, core[action.parent_type+'s']);
var parent = Object.assign({}, parent_index[action.parent_key]);
@ -569,7 +598,10 @@ const CoreMiddleware = (function(){
var records_uris = helpers.arrayOf('uri', records);
// Append our records_uris array with our new records
var uris = [...parent[records_type_plural+'_uris'], ...records_uris];
var uris = records_uris;
if (parent[records_type_plural+'_uris'] !== undefined){
uris = [...parent[records_type_plural+'_uris'], ...uris];
}
parent[records_type_plural+'_uris'] = uris;
if (action.records_data.next !== undefined){
parent[records_type_plural+'_more'] = action.records_data.next;

View File

@ -11,19 +11,14 @@ export default function reducer(core = {}, action){
* Current track and tracklist
**/
case 'MOPIDY_TLTRACKS':
if (!action.tracklist){
return core;
}
return Object.assign({}, core, { current_tracklist: action.tracklist });
case 'MOPIDY_CURRENTTLTRACK':
if (!action.data){
return core;
}
case 'CURRENT_TRACK_LOADED':
return Object.assign({}, core, {
current_tracklist: action.current_tracklist,
current_track: action.current_track
current_track_uri: action.current_track_uri
});
case 'QUEUE_LOADED':
return Object.assign({}, core, {
queue: action.tracks_uris
});
case 'PUSHER_QUEUE_METADATA':
@ -190,50 +185,6 @@ export default function reducer(core = {}, action){
* Playlists
**/
case 'PLAYLIST_KEY_UPDATED':
var playlists = Object.assign([], core.playlists)
// URI not in our index? No change needed then
if (typeof(playlists[action.key]) === 'undefined'){
return core
}
// Delete our old playlist by key, and add by new key
var playlist = Object.assign({}, playlists[action.key])
delete playlists[action.key]
playlists[playlist.uri] = playlist
return Object.assign({}, core, { playlists: playlists });
case 'PLAYLIST_LOADED_MORE_TRACKS':
var playlists = Object.assign([], core.playlists)
var playlist = Object.assign(
{},
playlists[action.key],
{
tracks: [...playlists[action.key].tracks, ...helpers.formatTracks(action.data.items)],
tracks_more: action.data.next,
tracks_total: action.data.total
}
)
playlists[action.key] = playlist
return Object.assign({}, core, { playlists: playlists });
case 'PLAYLIST_TRACKS_REMOVED':
var playlists = Object.assign([], core.playlists)
var playlist = Object.assign({}, playlists[action.key])
var tracks = Object.assign([], playlist.tracks)
var indexes = action.tracks_indexes.reverse()
for(var i = 0; i < indexes.length; i++){
tracks.splice(indexes[i], 1 )
}
var snapshot_id = null
if (action.snapshot_id ) snapshot_id = action.snapshot_id
Object.assign(playlist, { tracks: tracks, snapshot_id: snapshot_id })
playlists[action.key] = playlist
return Object.assign({}, core, { playlists: playlists });
case 'PLAYLIST_TRACKS':
var playlists = Object.assign([], core.playlists)
var playlist = Object.assign({}, playlists[action.key], { tracks: helpers.formatTracks(action.tracks) })
@ -241,29 +192,6 @@ export default function reducer(core = {}, action){
playlists[action.key] = playlist
return Object.assign({}, core, { playlists: playlists });
case 'PLAYLIST_TRACKS_REORDERED':
var playlists = Object.assign([], core.playlists)
var playlist = Object.assign({}, playlists[action.key])
var tracks = Object.assign([], playlist.tracks)
// handle insert_before offset if we're moving BENEATH where we're slicing tracks
var insert_before = action.insert_before
if (insert_before > action.range_start ) insert_before = insert_before - action.range_length
// cut our moved tracks into a new array
var tracks_to_move = tracks.splice(action.range_start, action.range_length)
tracks_to_move.reverse()
for(i = 0; i < tracks_to_move.length; i++){
tracks.splice(insert_before, 0, tracks_to_move[i])
}
var snapshot_id = null
if (action.snapshot_id ) snapshot_id = action.snapshot_id
Object.assign(playlist, { tracks: tracks, snapshot_id: snapshot_id })
playlists[action.key] = playlist
return Object.assign({}, core, { playlists: playlists });
case 'LIBRARY_PLAYLISTS_LOADED':
if (core.library_playlists){
var library_playlists = [...core.library_playlists, ...action.uris]

View File

@ -1,7 +1,7 @@
var coreActions = require('../core/actions')
var uiActions = require('../ui/actions')
var helpers = require('../../helpers')
var coreActions = require('../core/actions');
var uiActions = require('../ui/actions');
var helpers = require('../../helpers');
/**
* Send an ajax request to the LastFM API
@ -150,34 +150,9 @@ export function revokeAuthorization(){
return { type: 'LASTFM_AUTHORIZATION_REVOKED' }
}
export function connect(){
return (dispatch, getState) => {
dispatch({ type: 'LASTFM_CONNECTING' });
// Authorized? Multi-purpose our connection test to get the current user
if (getState().lastfm.session){
dispatch(getMe());
// Not authorized? Just use a generic lookup to test our connection
} else {
sendRequest(dispatch, getState, 'method=artist.getInfo&artist=Moby')
.then(
response => {
dispatch({ type: 'LASTFM_CONNECTED' })
},
error => {
dispatch({ type: 'LASTFM_DISCONNECTED' })
}
)
}
}
}
/**
* Signed requests
* TODO
**/
export function loveTrack(uri, artist, track){
@ -218,6 +193,35 @@ export function unloveTrack(uri, artist, track){
}
}
export function scrobble(track){
return (dispatch, getState) => {
var track_name = track.name;
var artist_name = "Unknown";
if (track.artists){
artist_name = track.artists[0].name;
}
var artist_name = encodeURIComponent(artist_name);
var params = 'method=track.scrobble';
params += '&track='+track_name+'&artist='+artist_name;
params += '&timestamp='+Math.floor(Date.now() / 1000);
sendSignedRequest(dispatch, getState, params)
.then(
response => {
console.log("Scrobbled", response);
},
error => {
dispatch(coreActions.handleException(
'Could not scrobble track',
error,
(error.description ? error.description : null)
));
}
)
}
}
/**
* Non-signed requests
@ -331,32 +335,3 @@ export function getTrack(track, artist_name = null, track_name = null){
}
}
export function scrobble(track){
return (dispatch, getState) => {
var track_name = track.name;
var artist_name = "Unknown";
if (track.artists){
artist_name = track.artists[0].name;
}
var artist_name = encodeURIComponent(artist_name);
var params = 'method=track.scrobble';
params += '&track='+track_name+'&artist='+artist_name;
params += '&timestamp='+Math.floor(Date.now() / 1000);
sendSignedRequest(dispatch, getState, params)
.then(
response => {
console.log("Scrobbled", response);
},
error => {
dispatch(coreActions.handleException(
'Could not scrobble track',
error,
(error.description ? error.description : null)
));
}
)
}
}

View File

@ -1259,11 +1259,11 @@ const MopidyMiddleware = (function(){
type: 'PLAYLIST_KEY_UPDATED',
key: action.key,
new_key: response.uri
})
hashHistory.push(global.baseURL+'playlist/'+response.uri)
});
hashHistory.push(global.baseURL+'playlist/'+encodeURIComponent(response.uri));
}
store.dispatch(uiActions.createNotification('Saved'))
store.dispatch(uiActions.createNotification('Saved'));
})
});
break
@ -1703,17 +1703,17 @@ const MopidyMiddleware = (function(){
* ======================================================================================
**/
case 'MOPIDY_TLTRACKS':
store.dispatch({
type: 'QUEUE_LOADED',
tracks: helpers.formatTracks(action.data)
})
break;
case 'MOPIDY_CURRENTTLTRACK':
if (action.data && action.data.track){
var track = helpers.formatTracks(action.data);
// Fire off our universal track index loader
store.dispatch({
type: 'TRACK_LOADED',
key: track.uri,
track: track
});
// We've got Spotify running, and it's a spotify track - go straight to the source!
if (helpers.uriSource(track.uri) == 'spotify' && store.getState().spotify.enabled){
store.dispatch(spotifyActions.getTrack(track.uri))
@ -1722,9 +1722,16 @@ const MopidyMiddleware = (function(){
} else {
store.dispatch(mopidyActions.getImages('tracks',[track.uri]))
}
}
next(action);
// Set our window title to the track title
helpers.setWindowTitle(track, store.getState().mopidy.play_state);
store.dispatch({
type: 'CURRENT_TRACK_LOADED',
current_track: track,
current_track_uri: track.uri
});
}
break;
case 'MOPIDY_GET_TRACK':

View File

@ -232,10 +232,6 @@ export function importAuthorization(data){
**/
export function getMe(){
return (dispatch, getState) => {
// flush out the previous store value
dispatch({ type: 'SPOTIFY_ME_LOADED', data: false });
sendRequest(dispatch, getState, 'me' )
.then(
response => {
@ -1192,7 +1188,7 @@ export function playArtistTopTracks(uri){
* ======================================================================================
**/
export function getUser(uri){
export function getUser(uri, and_playlists = false){
return (dispatch, getState) => {
// get the user
@ -1212,7 +1208,9 @@ export function getUser(uri){
}
)
dispatch(getUserPlaylists(uri))
if (and_playlists){
dispatch(getUserPlaylists(uri));
}
}
}
@ -1242,14 +1240,11 @@ export function getUserPlaylists(user_uri){
}
dispatch({
type: 'PLAYLISTS_LOADED',
playlists: playlists
});
dispatch({
type: 'SPOTIFY_USER_PLAYLISTS_LOADED',
key: user_uri,
data: response
type: 'LOADED_MORE',
parent_type: 'user',
parent_key: user_uri,
records_type: 'playlist',
records_data: response
});
},
error => {

View File

@ -415,7 +415,7 @@ const SpotifyMiddleware = (function(){
store.dispatch({
type: 'USERS_LOADED',
users: [action.data]
})
});
next(action);
break;

View File

@ -78,7 +78,14 @@ class Artist extends React.Component{
}
loadMore(){
this.props.spotifyActions.getURL(this.props.artist.albums_more, 'SPOTIFY_ARTIST_ALBUMS_LOADED', this.props.params.uri );
this.props.spotifyActions.loadMore(
this.props.artist.albums_more,
{
parent_type: 'artist',
parent_key: this.props.params.uri,
records_type: 'album'
}
);
}
inLibrary(){
@ -190,7 +197,7 @@ class Artist extends React.Component{
<h4>Albums</h4>
<section className="grid-wrapper no-top-padding">
<AlbumGrid albums={albums} />
<LazyLoadListener loading={this.props.artist.albums_more} loadMore={ () => this.loadMore() }/>
<LazyLoadListener loading={this.props.artist.albums_more} loadMore={() => this.loadMore()} />
</section>
</div>
)

View File

@ -14,6 +14,7 @@ import LazyLoadListener from '../components/LazyLoadListener'
import FollowButton from '../components/FollowButton'
import Header from '../components/Header'
import ContextMenuTrigger from '../components/ContextMenuTrigger'
import URILink from '../components/URILink'
import * as helpers from '../helpers'
import * as coreActions from '../services/core/actions'
@ -101,20 +102,20 @@ class Playlist extends React.Component{
// TODO: Once deletion occurs, remove playlist from global playlists list
delete(){
this.props.mopidyActions.deletePlaylist(this.props.playlist.uri )
this.props.mopidyActions.deletePlaylist(this.props.playlist.uri);
}
reorderTracks(indexes, index){
this.props.coreActions.reorderPlaylistTracks(this.props.playlist.uri, indexes, index, this.props.playlist.snapshot_id )
this.props.coreActions.reorderPlaylistTracks(this.props.playlist.uri, indexes, index, this.props.playlist.snapshot_id);
}
removeTracks(tracks_indexes){
this.props.coreActions.removeTracksFromPlaylist(this.props.playlist.uri, tracks_indexes )
this.props.coreActions.removeTracksFromPlaylist(this.props.playlist.uri, tracks_indexes);
}
inLibrary(){
var library = helpers.uriSource(this.props.params.uri)+'_library_playlists'
return (this.props[library] && this.props[library].indexOf(this.props.params.uri) > -1)
var library = helpers.uriSource(this.props.params.uri)+'_library_playlists';
return (this.props[library] && this.props[library].indexOf(this.props.params.uri) > -1);
}
renderActions(){
@ -195,8 +196,8 @@ class Playlist extends React.Component{
{ this.props.playlist.description ? <h2 className="description grey-text" dangerouslySetInnerHTML={{__html: this.props.playlist.description}}></h2> : null }
<ul className="details">
{ !this.props.slim_mode ? <li className="has-tooltip"><FontAwesome name={helpers.sourceIcon(this.props.params.uri )} /><span className="tooltip">{helpers.uriSource(this.props.params.uri )} playlist</span></li> : null }
{ this.props.playlist.owner && !this.props.slim_mode ? <li><Link to={'/user/'+this.props.playlist.owner.uri}>{this.props.playlist.owner.id}</Link></li> : null }
{ !this.props.slim_mode ? <li className="has-tooltip"><FontAwesome name={helpers.sourceIcon(this.props.params.uri )} /><span className="tooltip">{helpers.uriSource(this.props.params.uri)} playlist</span></li> : null }
{ this.props.playlist.owner && !this.props.slim_mode ? <li><URILink type="user" uri={this.props.playlist.owner.uri}>{this.props.playlist.owner.id}</URILink></li> : null }
{ this.props.playlist.followers ? <li>{this.props.playlist.followers.total.toLocaleString()} followers</li> : null }
{ this.props.playlist.last_modified ? <li>Edited <Dater type="ago" data={this.props.playlist.last_modified} /></li> : null }
<li>

View File

@ -92,6 +92,31 @@ class Queue extends React.Component{
}
}
var tracks = [];
if (this.props.queue && this.props.tracks){
for (var i = 0; i < this.props.queue.length; i++){
var uri = this.props.queue[i];
if (this.props.tracks.hasOwnProperty(uri)){
var track = this.props.tracks[uri];
track.playing = (track.uri == this.props.current_track_uri);
tracks.push(track);
}
}
}
// Merge our metadata with each track
for (var i = 0; i < tracks.length; i++){
var track = tracks[i];
if (this.props.queue_metadata["tlid_"+track.tlid] !== undefined){
track = Object.assign(
{},
track,
this.props.queue_metadata["tlid_"+track.tlid]
);
tracks[i] = track;
}
}
var options = (
<span>
{this.props.spotify_enabled ? <button className="no-hover" onClick={e => this.props.uiActions.openModal('edit_radio')}>
@ -133,11 +158,11 @@ class Queue extends React.Component{
show_source_icon={true}
context="queue"
className="queue-track-list"
tracks={this.props.current_tracklist}
removeTracks={tracks => this.removeTracks(tracks )}
playTracks={tracks => this.playTracks(tracks )}
playTrack={track => this.playTrack(track )}
reorderTracks={(indexes, index) => this.reorderTracks(indexes, index) } />
tracks={tracks}
removeTracks={tracks => this.removeTracks(tracks)}
playTracks={tracks => this.playTracks(tracks)}
playTrack={track => this.playTrack(track)}
reorderTracks={(indexes, index) => this.reorderTracks(indexes, index)} />
</section>
</div>
@ -158,8 +183,11 @@ const mapStateToProps = (state, ownProps) => {
spotify_enabled: state.spotify.enabled,
radio: state.core.radio,
radio_enabled: (state.core.radio && state.core.radio.enabled ? true : false),
current_tracklist: state.core.current_tracklist,
current_track: (state.core.current_track !== undefined && state.core.tracks !== undefined && state.core.tracks[state.core.current_track] !== undefined ? state.core.tracks[state.core.current_track] : null)
tracks: state.core.tracks,
queue: state.core.queue,
queue_metadata: state.core.queue_metadata,
current_track_uri: state.core.current_track_uri,
current_track: (state.core.tracks[state.core.current_track_uri] !== undefined ? state.core.tracks[state.core.current_track_uri] : null)
}
}

View File

@ -33,18 +33,20 @@ class User extends React.Component{
loadUser(props = this.props){
if (!props.user){
this.props.spotifyActions.getUser(props.params.uri);
this.props.spotifyActions.getUser(props.params.uri, true);
this.props.spotifyActions.following(props.params.uri);
}
// We got a user, but we haven't fetched their playlists yet
if (props.user && !props.user.playlists_uris){
this.props.spotifyActions.getUserPlaylists(props.params.uri);
}
}
loadMore(){
this.props.spotifyActions.getURL(this.props.user.playlists_more, 'SPOTIFY_USER_PLAYLISTS_LOADED', this.props.params.uri);
this.props.spotifyActions.loadMore(
this.props.user.playlists_more,
{
parent_type: 'user',
parent_key: this.props.params.uri,
records_type: 'playlist'
}
);
}
isMe(){
@ -105,7 +107,7 @@ class User extends React.Component{
<section className="grid-wrapper">
<h4>Playlists</h4>
<PlaylistGrid playlists={playlists} />
<LazyLoadListener enabled={this.props.user.playlists_more} loadMore={ () => this.loadMore() }/>
<LazyLoadListener loading={this.props.user.playlists_more} loadMore={() => this.loadMore()} />
</section>
</div>
</div>
@ -120,8 +122,7 @@ const mapStateToProps = (state, ownProps) => {
spotify_authorized: state.spotify.authorization,
me: state.spotify.me,
playlists: state.core.playlists,
user: (state.core.users && state.core.users[uri] !== undefined ? state.core.users[uri] : false),
users: state.core.users
user: (state.core.users[uri] !== undefined ? state.core.users[uri] : false)
};
}