diff --git a/src/js/bootstrap.js b/src/js/bootstrap.js index 0e89943b..5901fe30 100755 --- a/src/js/bootstrap.js +++ b/src/js/bootstrap.js @@ -21,6 +21,10 @@ var initialState = { mopidy: { host: window.location.hostname, port: 6680 + }, + spotify: { + country: 'NZ', + locale: 'en_NZ' } }; diff --git a/src/js/components/AlbumGrid.js b/src/js/components/AlbumGrid.js new file mode 100755 index 00000000..019147d7 --- /dev/null +++ b/src/js/components/AlbumGrid.js @@ -0,0 +1,28 @@ + +import React, { PropTypes } from 'react' +import AlbumGridItem from './AlbumGridItem' + +export default class AlbumGrid extends React.Component{ + + constructor(props) { + super(props); + } + + render(){ + if( this.props.items ){ + return ( + + ); + } + return null; + } +} + diff --git a/src/js/components/AlbumGridItem.js b/src/js/components/AlbumGridItem.js new file mode 100755 index 00000000..2118227c --- /dev/null +++ b/src/js/components/AlbumGridItem.js @@ -0,0 +1,21 @@ + +import React, { PropTypes } from 'react' +import { Link } from 'react-router' +import Thumbnail from './Thumbnail' + +export default class AlbumGridItem extends React.Component{ + + constructor(props) { + super(props); + } + + render(){ + var link = '/album/' + this.props.item.uri; + return ( + + + + ); + } +} + diff --git a/src/js/components/Thumbnail.js b/src/js/components/Thumbnail.js new file mode 100755 index 00000000..30d7b06a --- /dev/null +++ b/src/js/components/Thumbnail.js @@ -0,0 +1,26 @@ + +import React, { PropTypes } from 'react' + +export default class Thumbnail extends React.Component{ + + constructor(props) { + super(props); + } + + sizedImageURL(){ + var images = this.props.images; + switch( this.props.size ){ + case 'small': + break; + + default: + return images[images.length-1].url + } + } + + render(){ + return ( + + ); + } +} \ No newline at end of file diff --git a/src/js/services/localstorage/middleware.js b/src/js/services/localstorage/middleware.js index 952f1572..87060bb7 100755 --- a/src/js/services/localstorage/middleware.js +++ b/src/js/services/localstorage/middleware.js @@ -14,12 +14,20 @@ const localstorageMiddleware = (function(){ case 'MOPIDY_SET_CONFIG': var mopidy = { - host: action.host, - port: action.port + host: action.config.host, + port: action.config.port }; localStorage.setItem('mopidy', JSON.stringify(mopidy)); break; + case 'SPOTIFY_SET_CONFIG': + var spotify = { + country: action.config.country, + locale: action.config.locale + }; + localStorage.setItem('spotify', JSON.stringify(spotify)); + break; + case 'SPOTIFY_COMPLETE_AUTHORIZATION': var spotify = { authorized: true, diff --git a/src/js/services/mopidy/actions.js b/src/js/services/mopidy/actions.js index 91766e58..e760311d 100755 --- a/src/js/services/mopidy/actions.js +++ b/src/js/services/mopidy/actions.js @@ -3,6 +3,13 @@ * Actions and Action Creators **/ +export function setConfig( config ){ + return { + type: 'MOPIDY_SET_CONFIG', + config: config + } +} + export function connect(){ return { type: 'MOPIDY_CONNECT' @@ -15,14 +22,6 @@ export function disconnect(){ } } -export function setConfig( host, port ){ - return { - type: 'MOPIDY_SET_CONFIG', - host: host, - port: port - } -} - export function changeTrack( tlid ){ return { type: 'MOPIDY_CHANGE_TRACK', diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js index c03182e6..4554c439 100755 --- a/src/js/services/spotify/actions.js +++ b/src/js/services/spotify/actions.js @@ -3,6 +3,13 @@ * Actions and Action Creators **/ +export function setConfig( config ){ + return { + type: 'SPOTIFY_SET_CONFIG', + config: config + } +} + export function startAuthorization(){ return { type: 'SPOTIFY_START_AUTHORIZATION' diff --git a/src/js/services/spotify/middleware.js b/src/js/services/spotify/middleware.js index 74d74269..63dd7e49 100755 --- a/src/js/services/spotify/middleware.js +++ b/src/js/services/spotify/middleware.js @@ -33,8 +33,10 @@ const SpotifyMiddleware = (function(){ * The actual middleware inteceptor **/ return store => next => action => { - switch(action.type) { + var state = store.getState(); + + switch(action.type){ case 'SPOTIFY_LOAD_ALBUM': @@ -57,21 +59,32 @@ const SpotifyMiddleware = (function(){ case 'SPOTIFY_LOAD_ARTIST': store.dispatch({ type: 'SPOTIFY_ARTIST_LOADED', data: false }) + store.dispatch({ type: 'SPOTIFY_ARTIST_ALBUMS_LOADED', data: false }) + var id = action.uri.replace('spotify:artist:',''); sendRequest( false, 'artists/'+id ) .then( (response) => { store.dispatch({ type: 'SPOTIFY_ARTIST_LOADED', data: response }) }); + + sendRequest( false, 'artists/'+id+'/albums' ) + .then( (response) => { + store.dispatch({ type: 'SPOTIFY_ARTIST_ALBUMS_LOADED', data: response }) + }); + + sendRequest( false, 'artists/'+id+'/top-tracks?country='+state.spotify.country ) + .then( (response) => { + store.dispatch({ type: 'SPOTIFY_ARTIST_TRACKS_LOADED', data: response }) + }); break; case 'SPOTIFY_LOAD_LIBRARY_ARTISTS': store.dispatch({ type: 'SPOTIFY_LIBRARY_ARTISTS_LOADED', data: false }) - var token = store.getState().spotify.access_token; - sendRequest( token, 'me/following?type=artist' ) + sendRequest( state.spotify.access_token, 'me/following?type=artist' ) .then( (response) => { store.dispatch({ type: 'SPOTIFY_LIBRARY_ARTISTS_LOADED', data: response }) }); diff --git a/src/js/services/spotify/reducer.js b/src/js/services/spotify/reducer.js index ef72ab0d..6a1c6bd0 100755 --- a/src/js/services/spotify/reducer.js +++ b/src/js/services/spotify/reducer.js @@ -35,6 +35,12 @@ export default function reducer(spotify = {}, action){ case 'SPOTIFY_ARTIST_LOADED': return Object.assign({}, spotify, { artist: action.data }); + case 'SPOTIFY_ARTIST_ALBUMS_LOADED': + return Object.assign({}, spotify, { artist_albums: action.data }); + + case 'SPOTIFY_ARTIST_TRACKS_LOADED': + return Object.assign({}, spotify, { artist_top_tracks: action.data }); + case 'SPOTIFY_LIBRARY_ARTISTS_LOADED': return Object.assign({}, spotify, { libraryArtists: action.data }); diff --git a/src/js/views/Artist.js b/src/js/views/Artist.js index 4939d039..a58b2d7a 100755 --- a/src/js/views/Artist.js +++ b/src/js/views/Artist.js @@ -4,6 +4,8 @@ import { connect } from 'react-redux' import { bindActionCreators } from 'redux' import TrackList from '../components/TrackList' +import AlbumGrid from '../components/AlbumGrid' + import * as spotifyActions from '../services/spotify/actions' class Artist extends React.Component{ @@ -30,6 +32,8 @@ class Artist extends React.Component{

{ this.props.spotify.artist.name }

{ this.props.spotify.artist.followers.total.toLocaleString() } followers

+ { this.props.spotify.artist_top_tracks ? : null } + { this.props.spotify.artist_albums ? : null }
); } diff --git a/src/js/views/Settings.js b/src/js/views/Settings.js index 4cb17766..e31c0843 100755 --- a/src/js/views/Settings.js +++ b/src/js/views/Settings.js @@ -17,7 +17,9 @@ class Settings extends React.Component{ this.state = { mopidy_host: this.props.mopidy.host, - mopidy_port: this.props.mopidy.port + mopidy_port: this.props.mopidy.port, + spotify_country: this.props.spotify.country, + spotify_locale: this.props.spotify.locale }; } @@ -26,17 +28,22 @@ class Settings extends React.Component{ window.location.reload(true); } - setConfig(){ - this.props.mopidyActions.setConfig( this.state.mopidy_host, this.state.mopidy_port ); + setMopidyConfig(){ + this.props.mopidyActions.setConfig({ host: this.state.mopidy_host, port: this.state.mopidy_port }); window.location.reload(true); } + setSpotifyConfig(){ + this.props.spotifyActions.setConfig({ country: this.state.spotify_country, locale: this.state.spotify_locale }); + } + render(){ return (

Settings

+

Mopidy

-
this.setConfig()}> + this.setMopidyConfig()}>
+

Spotify

+
this.setSpotifyConfig()}> + + + +
+ + this.resetAllSettings()} />
); diff --git a/src/scss/app.scss b/src/scss/app.scss index 81b2d372..7aa20635 100755 --- a/src/scss/app.scss +++ b/src/scss/app.scss @@ -1,4 +1,8 @@ @import 'vendor/font-awesome/index'; + +@import 'global/reset'; +@import 'global/forms'; + @import 'components/track'; diff --git a/src/scss/global/_forms.scss b/src/scss/global/_forms.scss new file mode 100755 index 00000000..8f82eb81 --- /dev/null +++ b/src/scss/global/_forms.scss @@ -0,0 +1,14 @@ + +input { + padding: 5px 8px; + border: 1px solid #000000; +} + +button, +input[type="button"], +input[type="submit"] { + padding: 5px 8px; + background: #000000; + color: #FFFFFF; + border: 0; +} \ No newline at end of file diff --git a/src/scss/global/_reset.scss b/src/scss/global/_reset.scss new file mode 100755 index 00000000..abae607e --- /dev/null +++ b/src/scss/global/_reset.scss @@ -0,0 +1,7 @@ + +* { + border: 0; + margin: 0; + padding: 0; + outline: 0; +} \ No newline at end of file