Loading mopidy playlist and tracks

This commit is contained in:
James Barnsley
2016-11-01 11:49:04 +13:00
parent b302cd2ac0
commit 569121c71d
8 changed files with 379 additions and 108 deletions

View File

@ -956,6 +956,8 @@
exports.getNewReleases = getNewReleases;
exports.getURL = getURL;
var helpers = __webpack_require__(63);
/**
* Send an ajax request to the Spotify API
*
@ -1138,7 +1140,7 @@
// flush out the previous store value
dispatch({ type: 'SPOTIFY_TRACK_LOADED', data: false });
sendRequest(dispatch, getState, 'tracks/' + getFromUri('trackid', uri)).then(function (response) {
sendRequest(dispatch, getState, 'tracks/' + helpers.getFromUri('trackid', uri)).then(function (response) {
dispatch({
type: 'SPOTIFY_TRACK_LOADED',
data: response
@ -1164,11 +1166,11 @@
dispatch(getArtistAlbums(uri));
// get both the artist and the top tracks
$.when(sendRequest(dispatch, getState, 'artists/' + getFromUri('artistid', uri)).then(function (response) {
$.when(sendRequest(dispatch, getState, 'artists/' + helpers.getFromUri('artistid', uri)).then(function (response) {
Object.assign(artist, response);
}), sendRequest(dispatch, getState, 'artists/' + getFromUri('artistid', uri) + '/top-tracks?country=' + getState().spotify.country).then(function (response) {
}), sendRequest(dispatch, getState, 'artists/' + helpers.getFromUri('artistid', uri) + '/top-tracks?country=' + getState().spotify.country).then(function (response) {
Object.assign(artist, response);
}), sendRequest(dispatch, getState, 'artists/' + getFromUri('artistid', uri) + '/related-artists').then(function (response) {
}), sendRequest(dispatch, getState, 'artists/' + helpers.getFromUri('artistid', uri) + '/related-artists').then(function (response) {
Object.assign(artist, { related_artists: response.artists });
})).then(function () {
dispatch({
@ -1181,7 +1183,7 @@
function getArtistAlbums(uri) {
return function (dispatch, getState) {
sendRequest(dispatch, getState, 'artists/' + getFromUri('artistid', uri) + '/albums').then(function (response) {
sendRequest(dispatch, getState, 'artists/' + helpers.getFromUri('artistid', uri) + '/albums').then(function (response) {
dispatch({
type: 'SPOTIFY_ARTIST_ALBUMS_LOADED',
data: response
@ -1201,7 +1203,7 @@
// flush out the previous store value
dispatch({ type: 'SPOTIFY_ALBUM_LOADED', data: false });
sendRequest(dispatch, getState, 'albums/' + getFromUri('albumid', uri)).then(function (response) {
sendRequest(dispatch, getState, 'albums/' + helpers.getFromUri('albumid', uri)).then(function (response) {
// inject the parent album object into each track for consistent track objects
for (var i = 0; i < response.tracks.items.length; i++) {
@ -1230,7 +1232,7 @@
// flush out the previous store value
dispatch({ type: 'SPOTIFY_PLAYLIST_LOADED', data: false });
sendRequest(dispatch, getState, 'users/' + getFromUri('userid', uri) + '/playlists/' + getFromUri('playlistid', uri) + '?market=' + getState().spotify.country).then(function (response) {
sendRequest(dispatch, getState, 'users/' + helpers.getFromUri('userid', uri) + '/playlists/' + helpers.getFromUri('playlistid', uri) + '?market=' + getState().spotify.country).then(function (response) {
dispatch({
type: 'SPOTIFY_PLAYLIST_LOADED',
data: response
@ -1390,36 +1392,6 @@
});
};
}
/**
* Get an element from a URI
* @param element = string, the element we wish to extract
* @param uri = string
**/
function getFromUri(element, uri) {
var exploded = uri.split(':');
if (element == 'userid' && exploded[1] == 'user') return exploded[2];
if (element == 'playlistid' && exploded[3] == 'playlist') return exploded[4];
if (element == 'artistid' && exploded[1] == 'artist') return exploded[2];
if (element == 'albumid' && exploded[1] == 'album') return exploded[2];
if (element == 'trackid' && exploded[1] == 'track') return exploded[2];
return null;
}
/**
* Identify what kind of asset a URI is (playlist, album, etc)
* @param uri = string
* @return string
**/
function uriType(uri) {
var exploded = uri.split(':');
if (exploded[0] == 'spotify' && exploded[1] == 'track') return 'track';
if (exploded[0] == 'spotify' && exploded[1] == 'artist') return 'artist';
if (exploded[0] == 'spotify' && exploded[1] == 'album') return 'album';
if (exploded[0] == 'spotify' && exploded[1] == 'user' && exploded[3] == 'playlist') return 'playlist';
if (exploded[0] == 'spotify' && exploded[1] == 'user' && exploded.length == 3) return 'user';
return null;
}
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(65)))
/***/ },
@ -1748,6 +1720,7 @@
exports.previous = previous;
exports.getPlaylists = getPlaylists;
exports.getBrowse = getBrowse;
exports.getPlaylist = getPlaylist;
/**
* Actions and Action Creators
@ -1851,6 +1824,13 @@
value: { uri: uri }
};
}
function getPlaylist(uri) {
return {
type: 'MOPIDY_PLAYLIST',
data: { uri: uri }
};
}
/***/ },
/* 17 */
@ -7635,6 +7615,66 @@
return currentConnection;
};
/**
* Figure out a URI's source namespace
* @param uri = string
**/
var uriSource = exports.uriSource = function uriSource(uri) {
var exploded = uri.split(':');
return exploded[0];
};
/**
* Get an element from a URI
* @param element = string, the element we wish to extract
* @param uri = string
**/
var getFromUri = exports.getFromUri = function getFromUri(element, uri) {
var exploded = uri.split(':');
if (exploded[0] == 'spotify') {
if (element == 'userid' && exploded[1] == 'user') return exploded[2];
if (element == 'playlistid' && exploded[3] == 'playlist') return exploded[4];
if (element == 'artistid' && exploded[1] == 'artist') return exploded[2];
if (element == 'albumid' && exploded[1] == 'album') return exploded[2];
if (element == 'trackid' && exploded[1] == 'track') return exploded[2];
return null;
}
return null;
};
/**
* Identify what kind of asset a URI is (playlist, album, etc)
* @param uri = string
* @return string
**/
var uriType = exports.uriType = function uriType(uri) {
var exploded = uri.split(':');
if (exploded[0] == 'spotify') {
switch (exploded[1]) {
case 'track':
return 'track';
break;
case 'artist':
return 'artist';
break;
case 'album':
return 'album';
break;
case 'user':
if (exploded[3] == 'playlist') return 'playlist';
if (exploded.length == 3) return 'user';
return null;
break;
}
}
return null;
};
/***/ },
/* 64 */
@ -10637,7 +10677,7 @@
/* 95 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;var require;/* WEBPACK VAR INJECTION */(function(process) {/** @license MIT License (c) copyright 2010-2014 original author or authors */
var require;var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(process) {/** @license MIT License (c) copyright 2010-2014 original author or authors */
/** @author Brian Cavalier */
/** @author John Hann */
@ -19087,6 +19127,45 @@
});
break;
case 'MOPIDY_PLAYLIST':
instruct(socket, store, 'playlists.lookup', action.data).then(function (response) {
var playlist = response;
playlist.tracks = {
items: response.tracks,
total: response.tracks.length
};
var uris = [];
for (var i = 0; i < playlist.tracks.items.length; i++) {
uris.push(playlist.tracks.items[i].uri);
}
instruct(socket, store, 'library.lookup', { uris: uris }).then(function (response) {
for (var uri in response) {
if (response.hasOwnProperty(uri)) {
// find the track reference, and drop in the full track data
var getByURI = function getByURI(trackReference) {
return track.uri == trackReference.uri;
};
var track = response[uri][0];
var trackReferences = playlist.tracks.items.filter(getByURI);
// there could be multiple instances of this track, so accommodate this
for (var j = 0; j < trackReferences.length; j++) {
var key = playlist.tracks.items.indexOf(trackReferences[j]);
playlist.tracks.items[key] = track;
}
}
}
store.dispatch({ type: 'MOPIDY_PLAYLIST_LOADED', data: playlist });
});
});
break;
// This action is irrelevant to us, pass it on to the next middleware
default:
return next(action);
@ -19188,6 +19267,11 @@
browse: action.data
});
case 'MOPIDY_PLAYLIST_LOADED':
return Object.assign({}, mopidy, {
playlist: action.data
});
default:
return mopidy;
}
@ -20206,6 +20290,8 @@
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var helpers = __webpack_require__(63);
var Playlist = function (_React$Component) {
_inherits(Playlist, _React$Component);
@ -20215,30 +20301,40 @@
return _possibleConstructorReturn(this, (Playlist.__proto__ || Object.getPrototypeOf(Playlist)).call(this, props));
}
// on render
_createClass(Playlist, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.props.spotifyActions.getPlaylist(this.props.params.uri);
this.loadPlaylist();
}
// when props changed
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
if (nextProps.params.uri != this.props.params.uri) {
this.props.spotifyActions.getPlaylist(nextProps.params.uri);
this.loadPlaylist(nextProps);
} else if (!this.props.mopidy.connected && nextProps.mopidy.connected) {
if (helpers.uriSource(this.props.params.uri) == 'm3u') {
this.loadPlaylist(nextProps);
}
}
}
}, {
key: 'render',
value: function render() {
if (this.props.spotify.playlist) {
key: 'loadPlaylist',
value: function loadPlaylist() {
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props;
var source = helpers.uriSource(props.params.uri);
if (source == 'spotify') {
this.props.spotifyActions.getPlaylist(props.params.uri);
} else if (source == 'm3u' && props.mopidy.connected) {
this.props.mopidyActions.getPlaylist(props.params.uri);
}
}
}, {
key: 'renderSpotifyPlaylist',
value: function renderSpotifyPlaylist() {
if (this.props.spotify.playlist) {
var playlist = this.props.spotify.playlist;
var context = null;
if (playlist.owner.id == this.props.spotify.me.id) context = 'editable-playlist';
@ -20278,6 +20374,56 @@
}
return null;
}
}, {
key: 'renderMopidyPlaylist',
value: function renderMopidyPlaylist() {
if (this.props.mopidy.playlist) {
var playlist = this.props.mopidy.playlist;
return _react2.default.createElement(
'div',
{ className: 'view playlist-view' },
_react2.default.createElement(
'div',
{ className: 'intro' },
playlist.images ? _react2.default.createElement(_Thumbnail2.default, { size: 'large', images: playlist.images }) : null,
_react2.default.createElement(
'div',
{ className: 'details' },
_react2.default.createElement(
'div',
null,
'Last updated ',
playlist.last_modified
)
)
),
_react2.default.createElement(
'div',
{ className: 'main' },
_react2.default.createElement(
'div',
{ className: 'title' },
_react2.default.createElement(
'h1',
null,
playlist.name
)
),
_react2.default.createElement(_TrackList2.default, { tracks: playlist.tracks.items })
)
);
}
return null;
}
}, {
key: 'render',
value: function render() {
var source = helpers.uriSource(this.props.params.uri);
if (source == 'spotify') return this.renderSpotifyPlaylist();
if (source == 'm3u') return this.renderMopidyPlaylist();
return null;
}
}]);
return Playlist;

File diff suppressed because one or more lines are too long

View File

@ -48,4 +48,75 @@ export let getCurrentPusherConnection = function( connections, connectionid ){
if( !currentConnection ) return false;
return currentConnection;
}
/**
* Figure out a URI's source namespace
* @param uri = string
**/
export let uriSource = function( uri ){
var exploded = uri.split(':');
return exploded[0]
}
/**
* Get an element from a URI
* @param element = string, the element we wish to extract
* @param uri = string
**/
export let getFromUri = function( element, uri ){
var exploded = uri.split(':');
if( exploded[0] == 'spotify' ){
if( element == 'userid' && exploded[1] == 'user' )
return exploded[2];
if( element == 'playlistid' && exploded[3] == 'playlist' )
return exploded[4];
if( element == 'artistid' && exploded[1] == 'artist' )
return exploded[2];
if( element == 'albumid' && exploded[1] == 'album' )
return exploded[2];
if( element == 'trackid' && exploded[1] == 'track' )
return exploded[2];
return null;
}
return null
}
/**
* Identify what kind of asset a URI is (playlist, album, etc)
* @param uri = string
* @return string
**/
export let uriType = function( uri ){
var exploded = uri.split(':');
if( exploded[0] == 'spotify' ){
switch( exploded[1] ){
case 'track':
return 'track'
break;
case 'artist':
return 'artist'
break;
case 'album':
return 'album'
break;
case 'user':
if( exploded[3] == 'playlist' ) return 'playlist'
if( exploded.length == 3 ) return 'user'
return null
break;
}
}
return null;
}

View File

@ -103,3 +103,10 @@ export function getBrowse( uri ){
}
}
export function getPlaylist( uri ){
return {
type: 'MOPIDY_PLAYLIST',
data: { uri: uri }
}
}

View File

@ -154,6 +154,47 @@ const MopidyMiddleware = (function(){
})
break;
case 'MOPIDY_PLAYLIST':
instruct( socket, store, 'playlists.lookup', action.data )
.then( response => {
var playlist = response;
playlist.tracks = {
items: response.tracks,
total: response.tracks.length
}
var uris = [];
for( var i = 0; i < playlist.tracks.items.length; i++ ){
uris.push( playlist.tracks.items[i].uri );
}
instruct( socket, store, 'library.lookup', { uris: uris } )
.then( response => {
for(var uri in response){
if (response.hasOwnProperty(uri)) {
var track = response[uri][0];
// find the track reference, and drop in the full track data
function getByURI( trackReference ){
return track.uri == trackReference.uri
}
var trackReferences = playlist.tracks.items.filter(getByURI);
// there could be multiple instances of this track, so accommodate this
for( var j = 0; j < trackReferences.length; j++){
var key = playlist.tracks.items.indexOf( trackReferences[j] );
playlist.tracks.items[ key ] = track;
}
}
}
store.dispatch({ type: 'MOPIDY_PLAYLIST_LOADED', data: playlist });
})
})
break;
// This action is irrelevant to us, pass it on to the next middleware
default:
return next(action);

View File

@ -77,6 +77,11 @@ export default function reducer(mopidy = {}, action){
browse: action.data
});
case 'MOPIDY_PLAYLIST_LOADED':
return Object.assign({}, mopidy, {
playlist: action.data
});
default:
return mopidy
}

View File

@ -1,4 +1,6 @@
var helpers = require('../../helpers.js')
/**
* Send an ajax request to the Spotify API
*
@ -197,7 +199,7 @@ export function getTrack( uri ){
// flush out the previous store value
dispatch({ type: 'SPOTIFY_TRACK_LOADED', data: false });
sendRequest( dispatch, getState, 'tracks/'+ getFromUri('trackid', uri) )
sendRequest( dispatch, getState, 'tracks/'+ helpers.getFromUri('trackid', uri) )
.then( response => {
dispatch({
type: 'SPOTIFY_TRACK_LOADED',
@ -228,17 +230,17 @@ export function getArtist( uri ){
// get both the artist and the top tracks
$.when(
sendRequest( dispatch, getState, 'artists/'+ getFromUri('artistid', uri) )
sendRequest( dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) )
.then( response => {
Object.assign(artist, response);
}),
sendRequest( dispatch, getState, 'artists/'+ getFromUri('artistid', uri) +'/top-tracks?country='+getState().spotify.country )
sendRequest( dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) +'/top-tracks?country='+getState().spotify.country )
.then( response => {
Object.assign(artist, response);
}),
sendRequest( dispatch, getState, 'artists/'+ getFromUri('artistid', uri) +'/related-artists' )
sendRequest( dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) +'/related-artists' )
.then( response => {
Object.assign(artist, { related_artists: response.artists });
})
@ -254,7 +256,7 @@ export function getArtist( uri ){
export function getArtistAlbums( uri ){
return (dispatch, getState) => {
sendRequest( dispatch, getState, 'artists/'+ getFromUri('artistid', uri) +'/albums' )
sendRequest( dispatch, getState, 'artists/'+ helpers.getFromUri('artistid', uri) +'/albums' )
.then( response => {
dispatch({
type: 'SPOTIFY_ARTIST_ALBUMS_LOADED',
@ -275,7 +277,7 @@ export function getAlbum( uri ){
// flush out the previous store value
dispatch({ type: 'SPOTIFY_ALBUM_LOADED', data: false });
sendRequest( dispatch, getState, 'albums/'+ getFromUri('albumid', uri) )
sendRequest( dispatch, getState, 'albums/'+ helpers.getFromUri('albumid', uri) )
.then( response => {
// inject the parent album object into each track for consistent track objects
@ -305,7 +307,7 @@ export function getPlaylist( uri ){
// flush out the previous store value
dispatch({ type: 'SPOTIFY_PLAYLIST_LOADED', data: false });
sendRequest( dispatch, getState, 'users/'+ getFromUri('userid',uri) +'/playlists/'+ getFromUri('playlistid',uri) +'?market='+getState().spotify.country )
sendRequest( dispatch, getState, 'users/'+ helpers.getFromUri('userid',uri) +'/playlists/'+ helpers.getFromUri('playlistid',uri) +'?market='+getState().spotify.country )
.then( response => {
dispatch({
type: 'SPOTIFY_PLAYLIST_LOADED',
@ -479,47 +481,3 @@ export function getURL( url, action_name ){
});
}
}
/**
* Get an element from a URI
* @param element = string, the element we wish to extract
* @param uri = string
**/
function getFromUri( element, uri ){
var exploded = uri.split(':');
if( element == 'userid' && exploded[1] == 'user' )
return exploded[2];
if( element == 'playlistid' && exploded[3] == 'playlist' )
return exploded[4];
if( element == 'artistid' && exploded[1] == 'artist' )
return exploded[2];
if( element == 'albumid' && exploded[1] == 'album' )
return exploded[2];
if( element == 'trackid' && exploded[1] == 'track' )
return exploded[2];
return null;
}
/**
* Identify what kind of asset a URI is (playlist, album, etc)
* @param uri = string
* @return string
**/
function uriType( uri ){
var exploded = uri.split(':');
if( exploded[0] == 'spotify' && exploded[1] == 'track' )
return 'track';
if( exploded[0] == 'spotify' && exploded[1] == 'artist' )
return 'artist';
if( exploded[0] == 'spotify' && exploded[1] == 'album' )
return 'album';
if( exploded[0] == 'spotify' && exploded[1] == 'user' && exploded[3] == 'playlist' )
return 'playlist';
if( exploded[0] == 'spotify' && exploded[1] == 'user' && exploded.length == 3 )
return 'user';
return null;
}

View File

@ -9,6 +9,7 @@ import Dater from '../components/Dater'
import * as spotifyActions from '../services/spotify/actions'
import * as mopidyActions from '../services/mopidy/actions'
let helpers = require('../helpers.js')
class Playlist extends React.Component{
@ -16,22 +17,33 @@ class Playlist extends React.Component{
super(props);
}
// on render
componentDidMount(){
this.props.spotifyActions.getPlaylist( this.props.params.uri );
this.loadPlaylist();
}
// when props changed
componentWillReceiveProps( nextProps ){
if( nextProps.params.uri != this.props.params.uri ){
this.props.spotifyActions.getPlaylist( nextProps.params.uri );
this.loadPlaylist( nextProps )
}else if( !this.props.mopidy.connected && nextProps.mopidy.connected ){
if( helpers.uriSource( this.props.params.uri ) == 'm3u' ){
this.loadPlaylist( nextProps )
}
}
}
render(){
if( this.props.spotify.playlist ){
loadPlaylist( props = this.props ){
var source = helpers.uriSource( props.params.uri );
if( source == 'spotify' ){
this.props.spotifyActions.getPlaylist( props.params.uri );
}else if( source == 'm3u' && props.mopidy.connected ){
this.props.mopidyActions.getPlaylist( props.params.uri );
}
}
renderSpotifyPlaylist(){
if( this.props.spotify.playlist ){
var playlist = this.props.spotify.playlist;
var context = null;
if( playlist.owner.id == this.props.spotify.me.id ) context = 'editable-playlist'
@ -52,6 +64,37 @@ class Playlist extends React.Component{
</div>
);
}
return null;
}
renderMopidyPlaylist(){
if( this.props.mopidy.playlist ){
var playlist = this.props.mopidy.playlist;
return (
<div className="view playlist-view">
<div className="intro">
{ playlist.images ? <Thumbnail size="large" images={ playlist.images } /> : null }
<div className="details">
<div>Last updated { playlist.last_modified }</div>
</div>
</div>
<div className="main">
<div className="title">
<h1>{ playlist.name }</h1>
</div>
<TrackList tracks={ playlist.tracks.items } />
</div>
</div>
);
}
return null;
}
render(){
var source = helpers.uriSource( this.props.params.uri );
if( source == 'spotify' ) return this.renderSpotifyPlaylist();
if( source == 'm3u' ) return this.renderMopidyPlaylist();
return null;
}
}