From ab9f317aed6c1361dd17b32f5a22f7a2be5c0aa6 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Tue, 25 Oct 2016 17:01:37 +1300 Subject: [PATCH] Parallax setup --- src/images/{icons => }/no-image.svg | 0 src/js/components/ListItem.js | 4 +++- src/js/components/Parallax.js | 33 ++++++++++++++++++++++++++ src/js/components/RelatedArtistList.js | 29 ++++++++++++++++++++++ src/js/components/Thumbnail.js | 32 +++++++++++++++++-------- src/js/helpers.js | 32 +++++++++++++++++++++++++ src/js/services/spotify/actions.js | 9 +++++-- src/js/views/Artist.js | 6 +++++ src/js/views/Queue.js | 1 - src/js/views/Settings.js | 4 ++-- src/scss/app.scss | 3 +++ src/scss/components/_images.scss | 29 ++++++++++++++++++++++ src/scss/components/_sidebar.scss | 14 +++++++++-- src/scss/global/_core.scss | 7 ++++-- src/scss/views/_artist.scss | 10 ++++++++ 15 files changed, 193 insertions(+), 20 deletions(-) rename src/images/{icons => }/no-image.svg (100%) create mode 100755 src/js/components/Parallax.js create mode 100755 src/js/components/RelatedArtistList.js create mode 100755 src/js/helpers.js create mode 100755 src/scss/components/_images.scss create mode 100755 src/scss/views/_artist.scss diff --git a/src/images/icons/no-image.svg b/src/images/no-image.svg similarity index 100% rename from src/images/icons/no-image.svg rename to src/images/no-image.svg diff --git a/src/js/components/ListItem.js b/src/js/components/ListItem.js index 92b9d4bf..394f4481 100755 --- a/src/js/components/ListItem.js +++ b/src/js/components/ListItem.js @@ -10,7 +10,9 @@ export default class ListItem extends React.Component{ } handleClick(e){ - browserHistory.push( this.props.link ); + if( e.target.tagName.toLowerCase() !== 'a' ){ + browserHistory.push( this.props.link ); + } } render(){ diff --git a/src/js/components/Parallax.js b/src/js/components/Parallax.js new file mode 100755 index 00000000..aa07b685 --- /dev/null +++ b/src/js/components/Parallax.js @@ -0,0 +1,33 @@ + +import React, { PropTypes } from 'react' +import * as helpers from '../helpers' + +export default class Parallax extends React.Component{ + + constructor(props) { + super(props); + + this.state = { + image: false + } + } + + componentDidMount(){ + this.setState({ + image: helpers.SizedImages( this.props.images ) + }) + this.update(); + } + + update(){ + // TODO: copy canvas rules in here from Spotmop + } + + render(){ + return ( +
+ { this.state.image ? : null } +
+ ); + } +} \ No newline at end of file diff --git a/src/js/components/RelatedArtistList.js b/src/js/components/RelatedArtistList.js new file mode 100755 index 00000000..292e5515 --- /dev/null +++ b/src/js/components/RelatedArtistList.js @@ -0,0 +1,29 @@ + +import React, { PropTypes } from 'react' +import { Link } from 'react-router' +import Thumbnail from './Thumbnail' + +export default class RelatedArtistList extends React.Component{ + + constructor(props) { + super(props); + } + + render(){ + return ( + + { + this.props.artists.map( (artist, index) => { + var link = '/artist/' + artist.uri; + return ( + + + { artist.name } + + ); + }) + } + + ); + } +} \ No newline at end of file diff --git a/src/js/components/Thumbnail.js b/src/js/components/Thumbnail.js index 516b6a07..d81ffa26 100755 --- a/src/js/components/Thumbnail.js +++ b/src/js/components/Thumbnail.js @@ -1,5 +1,6 @@ import React, { PropTypes } from 'react' +import * as helpers from '../helpers' export default class Thumbnail extends React.Component{ @@ -24,22 +25,33 @@ export default class Thumbnail extends React.Component{ mapImageSizes(){ var images = this.props.images; - for( var i = 0; i < images.length; i++ ){ - if( images[i].height > 800 ){ - this.setState({ huge: images[i].url }); - }else if( images[i].height > 600 ){ - this.setState({ large: images[i].url }); - }else if( images[i].height > 280 ){ - this.setState({ medium: images[i].url }); - }else{ - this.setState({ small: images[i].url }); + var state = this.state; + + if( images.length <= 0 ){ + state = { + small: require('../../images/no-image.svg'), + medium: require('../../images/no-image.svg'), + large: require('../../images/no-image.svg'), + huge: require('../../images/no-image.svg') } + }else{ + state = helpers.SizedImages( images ); } + + this.setState( state ); } render(){ + var style = { + backgroundImage: 'url("'+this.state[this.props.size]+'")' + } + var className = 'thumbnail '+this.props.size; + if( this.props.circle ) className += ' circle'; + return ( - +
+
+
); } } \ No newline at end of file diff --git a/src/js/helpers.js b/src/js/helpers.js new file mode 100755 index 00000000..d996f338 --- /dev/null +++ b/src/js/helpers.js @@ -0,0 +1,32 @@ + + +export let SizedImages = function( images ){ + + var sizes = { + small: false, + medium: false, + large: false, + huge: false + } + + if( images.length > 0 ){ + + for( var i = 0; i < images.length; i++ ){ + if( images[i].height > 800 ){ + sizes.huge = images[i].url; + }else if( images[i].height > 600 ){ + sizes.large = images[i].url; + }else if( images[i].height > 280 ){ + sizes.medium = images[i].url; + }else{ + sizes.small = images[i].url; + } + } + + if( !sizes.medium ) sizes.medium = sizes.small; + if( !sizes.large ) sizes.large = sizes.medium; + if( !sizes.huge ) sizes.huge = sizes.large; + } + + return sizes; +} \ No newline at end of file diff --git a/src/js/services/spotify/actions.js b/src/js/services/spotify/actions.js index 1fb2e967..194eb416 100755 --- a/src/js/services/spotify/actions.js +++ b/src/js/services/spotify/actions.js @@ -199,9 +199,14 @@ export function getArtist( uri ){ Object.assign(artist, response); }), - sendRequest( dispatch, getState, 'artists/'+ getFromUri('artistid', uri) +'/top-tracks?country='+getState().spotify.country ) + sendRequest( dispatch, getState, 'artists/'+ getFromUri('artistid', uri) +'/top-tracks?country='+getState().spotify.country ) + .then( response => { + Object.assign(artist, response); + }), + + sendRequest( dispatch, getState, 'artists/'+ getFromUri('artistid', uri) +'/related-artists' ) .then( response => { - Object.assign(artist, response); + Object.assign(artist, { related_artists: response.artists }); }) ).then( () => { diff --git a/src/js/views/Artist.js b/src/js/views/Artist.js index 713c4682..03919deb 100755 --- a/src/js/views/Artist.js +++ b/src/js/views/Artist.js @@ -6,6 +6,9 @@ import { bindActionCreators } from 'redux' import Header from '../components/Header' import TrackList from '../components/TrackList' import AlbumGrid from '../components/AlbumGrid' +import Thumbnail from '../components/Thumbnail' +import Parallax from '../components/Parallax' +import RelatedArtistList from '../components/RelatedArtistList' import * as spotifyActions from '../services/spotify/actions' @@ -32,7 +35,10 @@ class Artist extends React.Component{ return (
+ { this.props.spotify.artist.images ? : null } + { this.props.spotify.artist.images ? : null }

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

+ { this.props.spotify.artist.related_artists ? : null } { this.props.spotify.artist.tracks ? : null } { this.props.spotify.artist_albums ? : null }
diff --git a/src/js/views/Queue.js b/src/js/views/Queue.js index 9c0694cd..9a2fc43e 100755 --- a/src/js/views/Queue.js +++ b/src/js/views/Queue.js @@ -67,7 +67,6 @@ class Queue extends React.Component{ title="Now playing" /> { this.renderTrackInFocus() } -

Other tracks

{ this.renderTrackList() } ); diff --git a/src/js/views/Settings.js b/src/js/views/Settings.js index fd9f6898..018e9ee1 100755 --- a/src/js/views/Settings.js +++ b/src/js/views/Settings.js @@ -48,7 +48,7 @@ class Settings extends React.Component{
-

Mopidy

+

Mopidy

this.setMopidyConfig()}>