diff --git a/build.sh b/build.sh
index aced77c7..879480a0 100755
--- a/build.sh
+++ b/build.sh
@@ -20,5 +20,7 @@ CACHEBUSTER=$(date | md5sum | cut -f1 -d' ')
echo -e Cachebusting js/css URLs $CACHEBUSTER
sed -i 's/app.js/app.min.js?'$CACHEBUSTER'/g' mopidy_iris/static/index.html
sed -i 's/app.css/app.min.css?'$CACHEBUSTER'/g' mopidy_iris/static/index.html
+sed -i 's/app.js/app.js?'$CACHEBUSTER'/g' mopidy_iris/static/test.html
+sed -i 's/app.css/app.css?'$CACHEBUSTER'/g' mopidy_iris/static/test.html
echo -e "\x1b[32;01m"Done!"\x1b[39;49;00m"
\ No newline at end of file
diff --git a/src/js/components/FollowButton.js b/src/js/components/FollowButton.js
index 0e65d0a1..42e62ce2 100755
--- a/src/js/components/FollowButton.js
+++ b/src/js/components/FollowButton.js
@@ -30,7 +30,21 @@ class FollowButton extends React.Component{
render(){
if( !this.props.spotify_authorized || !this.props.uri ) return false
- var item = this.props[helpers.uriType( this.props.uri )]
+ var item = {}
+ switch (helpers.uriType( this.props.uri )){
+ case 'artist':
+ item = this.props.artists[this.props.uri]
+ break
+ case 'user':
+ item = this.props.users[this.props.uri]
+ break
+ case 'album':
+ item = this.props.albums[this.props.uri]
+ break
+ case 'playlist':
+ item = this.props.playlists[this.props.uri]
+ break
+ }
if( item.following === true ){
return
@@ -43,10 +57,10 @@ class FollowButton extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
spotify_authorized: state.spotify.authorized,
- artist: state.ui.artist,
- user: state.ui.user,
- album: state.ui.album,
- playlist: state.ui.playlist
+ artists: state.ui.artists,
+ users: state.ui.users,
+ albums: state.ui.albums,
+ playlists: state.ui.playlists
}
}
diff --git a/src/js/components/GridItem.js b/src/js/components/GridItem.js
index bd3a2d50..addbd4f2 100755
--- a/src/js/components/GridItem.js
+++ b/src/js/components/GridItem.js
@@ -24,6 +24,32 @@ export default class GridItem extends React.Component{
return
}
+ renderSecondary(item){
+ var output = ''
+
+ switch (item.type){
+
+ case 'playlist':
+ return (
+
+ { item.tracks_total ? item.tracks_total+' tracks' : null }
+ { item.can_edit ? : null }
+
+ )
+ break
+
+ default:
+ return (
+
+ { item.artists ? : null }
+ { item.followers ? item.followers.total.toLocaleString()+' followers' : null }
+
+ )
+ }
+
+ return output
+ }
+
render(){
if( !this.props.item ) return null
@@ -37,10 +63,7 @@ export default class GridItem extends React.Component{
{ this.renderThumbnail() }
{ item.name }
- { item.artists ?
: null }
- { item.type == 'playlist' && item.tracks_total ? item.tracks_total+' tracks' : null }
- { item.followers ? item.followers.total.toLocaleString()+' followers' : null }
- { item.type == 'playlist' && item.can_edit ?
: null }
+ { this.renderSecondary(item) }
);
diff --git a/src/js/helpers.js b/src/js/helpers.js
index 17cb6a8c..15e74f08 100755
--- a/src/js/helpers.js
+++ b/src/js/helpers.js
@@ -196,6 +196,18 @@ export let uriType = function( uri ){
}
+/**
+ * Convert a raw URI into a object index-friendly format. Primarily used for loading local playlists
+ * @param $uri = string
+ * @return string
+ **/
+export let indexFriendlyUri = function (uri){
+ var output = encodeURI(uri)
+ output = output.replace("'",'%27')
+ return output
+}
+
+
/**
* Digest an array of objects, and pull into simple array of uris
*
diff --git a/src/js/services/localstorage/middleware.js b/src/js/services/localstorage/middleware.js
index 435627b4..b04cc042 100755
--- a/src/js/services/localstorage/middleware.js
+++ b/src/js/services/localstorage/middleware.js
@@ -12,7 +12,7 @@ const localstorageMiddleware = (function(){
// append our state to a global variable. This gives us access to debug the store at any point
window._store = store
- console.log(action)
+ //console.log(action)
switch( action.type ){
diff --git a/src/js/services/mopidy/middleware.js b/src/js/services/mopidy/middleware.js
index f10054fe..edc1b07f 100755
--- a/src/js/services/mopidy/middleware.js
+++ b/src/js/services/mopidy/middleware.js
@@ -304,14 +304,11 @@ const MopidyMiddleware = (function(){
var playlist = Object.assign(
{},
{
- images: []
- },
- {
- can_edit: (response.uri.startsWith('m3u:'))
- },
- response,
- {
- tracks: ( response.tracks ? response.tracks : [] ),
+ type: 'playlist',
+ name: response.name,
+ uri: response.uri,
+ last_modified: response.last_modified,
+ can_edit: (response.uri.startsWith('m3u:')),
tracks_total: ( response.tracks ? response.tracks.length : 0 )
}
)
@@ -328,18 +325,16 @@ const MopidyMiddleware = (function(){
.then( response => {
var playlist = Object.assign(
{},
- {
- images: []
- },
response,
{
- tracks: ( response.tracks ? response.tracks : [] ),
- tracks_total: ( response.tracks ? response.tracks.length : 0 )
+ type: 'playlist',
+ tracks: ( response.tracks ? response.tracks : null ),
+ tracks_total: ( response.tracks ? response.tracks.length : null )
}
)
// tracks? get the full track objects
- if( playlist.tracks.length > 0 ) store.dispatch({ type: 'MOPIDY_RESOLVE_PLAYLIST_TRACKS', tracks: playlist.tracks })
+ if( playlist.tracks.length > 0 ) store.dispatch({ type: 'MOPIDY_RESOLVE_PLAYLIST_TRACKS', tracks: playlist.tracks, uri: response.uri })
store.dispatch({ type: 'PLAYLIST_LOADED', playlist: playlist })
})
@@ -372,7 +367,7 @@ const MopidyMiddleware = (function(){
}
}
- store.dispatch({ type: 'PLAYLIST_TRACKS_LOADED', playlist_uri: action.playlist_uri, tracks: tracks })
+ store.dispatch({ type: 'PLAYLIST_TRACKS_RESOLVED', tracks: tracks, uri: action.uri })
})
break
diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js
index 4034ae29..e6046f44 100755
--- a/src/js/services/spotify/actions.js
+++ b/src/js/services/spotify/actions.js
@@ -263,9 +263,19 @@ export function getFeaturedPlaylists(){
sendRequest( dispatch, getState, 'browse/featured-playlists?timestamp='+timestamp+'&country='+getState().spotify.country+'&limit=50&locale='+getState().spotify.locale )
.then( response => {
for (var i = 0; i < response.playlists.items.length; i++){
+
+ var playlist = response.playlists.items[i]
+ Object.assign(
+ playlist,
+ {
+ can_edit: (getState().spotify.me && playlist.owner.id == getState().spotify.me.id),
+ tracks_total: playlist.tracks.total
+ }
+ )
+
dispatch({
type: 'PLAYLIST_LOADED',
- playlist: response.playlists.items[i]
+ playlist: playlist
});
}
dispatch({
@@ -306,18 +316,22 @@ export function getCategory( id ){
).then( ( category_response, playlists_response ) => {
- var playlists = []
for (var i = 0; i < playlists_response.playlists.items.length; i++){
- playlists.push(
- Object.assign(
- {},
- playlists_response.playlists.items[i],
- {
- tracks: false,
- tracks_total: playlists_response.playlists.items[i].tracks.total
- }
- )
+
+ var playlist = Object.assign(
+ {},
+ playlists_response.playlists.items[i],
+ {
+ tracks: null,
+ tracks_more: null,
+ tracks_total: playlists_response.playlists.items[i].tracks.total
+ }
)
+
+ dispatch({
+ type: 'PLAYLIST_LOADED',
+ playlist: playlist
+ });
}
var category = Object.assign(
@@ -325,10 +339,14 @@ export function getCategory( id ){
category_response,
{
items: false,
- playlists: playlists
+ playlists: helpers.asURIs(playlists_response.playlists.items),
+ playlists_more: playlists_response.playlists.next,
+ playlists_total: playlists_response.playlists.total
}
)
+ console.log(category)
+
dispatch({
type: 'SPOTIFY_CATEGORY_LOADED',
data: category
@@ -358,8 +376,8 @@ export function getURL( url, action_name, uri = false ){
.then( response => {
dispatch({
type: action_name,
- data: response,
- uri: uri
+ uri: uri,
+ data: response
});
});
}
@@ -829,27 +847,20 @@ function loadNextPlaylistsBatch( dispatch, getState, playlists, lastResponse ){
});
}else{
- // check our editability of each playlist
- // used to define what we can add tracks to
- if( getState().spotify.authorized ){
- for( var i = 0; i < playlists.length; i++ ){
+ for( var i = 0; i < playlists.length; i++ ){
+ var playlist = Object.assign(
+ {},
+ playlists[i],
+ {
+ can_edit: (getState().spotify.authorized && getState().spotify.me && playlists[i].owner.id == getState().spotify.me.id),
+ tracks_total: playlists[i].tracks.total
+ }
+ )
- var playlist = Object.assign(
- {},
- playlists[i],
- {
- can_edit: (getState().spotify.me && playlists[i].owner.id == getState().spotify.me.id),
- tracks: helpers.flattenTracks(playlists[i].tracks.items),
- tracks_more: response.tracks.next,
- tracks_total: response.tracks.total
- }
- )
-
- dispatch({
- type: 'PLAYLIST_LOADED',
- playlist: playlist
- });
- }
+ dispatch({
+ type: 'PLAYLIST_LOADED',
+ playlist: playlist
+ });
}
dispatch({
diff --git a/src/js/services/spotify/reducer.js b/src/js/services/spotify/reducer.js
index cd91ae27..9168d64f 100755
--- a/src/js/services/spotify/reducer.js
+++ b/src/js/services/spotify/reducer.js
@@ -156,9 +156,7 @@ export default function reducer(spotify = {}, action){
case 'SPOTIFY_CATEGORY_LOADED':
return Object.assign({}, spotify, { category: action.data })
- case 'SPOTIFY_CATEGORY_PLAYLISTS_LOADED':
- return Object.assign({}, spotify, { category_playlists: action.data })
-
+ // TODO: update this
case 'SPOTIFY_CATEGORY_PLAYLISTS_LOADED_MORE':
return Object.assign({}, spotify, { category_playlists: {
href: action.data.href,
diff --git a/src/js/services/ui/reducer.js b/src/js/services/ui/reducer.js
index a7024819..f9d29fc3 100755
--- a/src/js/services/ui/reducer.js
+++ b/src/js/services/ui/reducer.js
@@ -114,9 +114,6 @@ export default function reducer(ui = {}, action){
current_track: current_track
});
- case 'FOLLOWING_LOADING':
- return Object.assign({}, ui, { following_loading: true })
-
case 'RADIO':
case 'START_RADIO':
return Object.assign({}, ui, { seeds_resolved: false }, { radio: action.data.radio })
@@ -223,17 +220,25 @@ export default function reducer(ui = {}, action){
* Playlists
**/
+ case 'PLAYLIST_LOADED':
case 'PLAYLIST_UPDATED':
- var playlist = Object.assign({}, ui.playlist, action.playlist)
- return Object.assign({}, ui, { playlist: playlist })
+ var playlists = Object.assign([], ui.playlists)
+ var playlist = Object.assign({}, action.playlist)
+
+ // if we already have one in our list, fetch it and update it
+ if (playlists[action.playlist.uri]){
+ playlist = Object.assign({}, playlists[action.playlist.uri], action.playlist)
+ }
+
+ playlists[action.playlist.uri] = playlist
+ return Object.assign({}, ui, { playlists: playlists });
case 'MOPIDY_PLAYLIST_LOADED':
if( !action.data ) return Object.assign({}, ui, { playlist: false })
return Object.assign({}, ui, { playlist: action.data })
case 'PLAYLIST_LOADED_MORE_TRACKS':
-
- var playlists = ui.playlists
+ var playlists = Object.assign([], ui.playlists)
var playlist = Object.assign(
{},
playlists[action.uri],
@@ -258,9 +263,12 @@ export default function reducer(ui = {}, action){
var playlist = Object.assign({}, ui.playlist, { tracks: tracks, snapshot_id: snapshot_id })
return Object.assign({}, ui, { playlist: playlist });
- case 'PLAYLIST_TRACKS_LOADED':
- var playlist = Object.assign({}, ui.playlist, { tracks: action.tracks })
- return Object.assign({}, ui, { playlist: playlist });
+ case 'PLAYLIST_TRACKS_RESOLVED':
+ var playlists = Object.assign([], ui.playlists)
+ var playlist = Object.assign({}, playlists[action.uri], { tracks: action.tracks })
+
+ playlists[action.uri] = playlist
+ return Object.assign({}, ui, { playlists: playlists });
case 'PLAYLIST_TRACKS_REORDERED':
var snapshot_id = null
@@ -283,25 +291,10 @@ export default function reducer(ui = {}, action){
return Object.assign({}, ui, { playlist: playlist });
case 'PLAYLIST_FOLLOWING_LOADED':
- var playlist = Object.assign({}, ui.playlist, { following: action.is_following })
- return Object.assign({}, ui, { playlist: playlist, following_loading: false });
+ var playlists = Object.assign([], ui.playlists)
+ var playlist = Object.assign({}, playlists[action.uri], { following: action.is_following })
-
- /**
- * Library Playlists
- **/
-
- case 'PLAYLIST_LOADED':
- case 'PLAYLIST_UPDATED':
- var playlists = ui.playlists
- var playlist = Object.assign({}, action.playlist)
-
- // if we already have one in our list, fetch it and update it
- if (playlists[action.playlist.uri]){
- playlist = Object.assign({}, playlists[action.playlist.uri], action.playlist)
- }
-
- playlists[action.playlist.uri] = playlist
+ playlists[action.uri] = playlist
return Object.assign({}, ui, { playlists: playlists });
case 'LIBRARY_PLAYLISTS_LOADED':
diff --git a/src/js/views/Playlist.js b/src/js/views/Playlist.js
index faa42ca4..55927ceb 100755
--- a/src/js/views/Playlist.js
+++ b/src/js/views/Playlist.js
@@ -173,7 +173,7 @@ class Playlist extends React.Component{
const mapStateToProps = (state, ownProps) => {
return {
- playlist: state.ui.playlists[ownProps.params.uri],
+ playlist: state.ui.playlists[helpers.indexFriendlyUri(ownProps.params.uri)],
mopidy_connected: state.mopidy.connected,
spotify_authorized: state.spotify.authorized,
spotify_userid: state.spotify.me.id
diff --git a/src/js/views/discover/DiscoverCategory.js b/src/js/views/discover/DiscoverCategory.js
index 769f1188..a22f5026 100755
--- a/src/js/views/discover/DiscoverCategory.js
+++ b/src/js/views/discover/DiscoverCategory.js
@@ -26,18 +26,26 @@ class DiscoverCategory extends React.Component{
}
loadMore(){
- if( !this.props.spotify.new_releases || !this.props.spotify.new_releases.next ) return
- this.props.spotifyActions.getURL( this.props.spotify.new_releases.next, 'SPOTIFY_NEW_RELEASES_LOADED_MORE' );
+ if( !this.props.playlists_next || !this.props.playlists_next ) return
+ this.props.spotifyActions.getURL( this.props.playlists_next, 'SPOTIFY_NEW_RELEASES_LOADED_MORE' );
}
render(){
- if( !this.props.spotify.category ) return null;
+ if (!this.props.category) return null
+
+ var playlists = []
+ for (var i = 0; i < this.props.category.playlists.length; i++){
+ var uri = this.props.category.playlists[i]
+ if (this.props.playlists.hasOwnProperty(uri)){
+ playlists.push(this.props.playlists[uri])
+ }
+ }
return (
-
+
- { this.props.spotify.category.playlists ? : null }
+
this.loadMore() }/>
@@ -53,7 +61,10 @@ class DiscoverCategory extends React.Component{
**/
const mapStateToProps = (state, ownProps) => {
- return state;
+ return {
+ playlists: state.ui.playlists,
+ category: state.spotify.category
+ }
}
const mapDispatchToProps = (dispatch) => {
diff --git a/src/js/views/library/LibraryPlaylists.js b/src/js/views/library/LibraryPlaylists.js
index f4f2ef00..8d8273a5 100755
--- a/src/js/views/library/LibraryPlaylists.js
+++ b/src/js/views/library/LibraryPlaylists.js
@@ -67,7 +67,7 @@ class LibraryPlaylists extends React.Component{
{
width: 10,
label: 'Tracks',
- name: 'tracks.total'
+ name: 'tracks_total'
}
]
return (