Grid and list fields; Dater sentence; Testing parallax

This commit is contained in:
James Barnsley
2016-11-04 09:35:39 +13:00
parent 6cee0a9daf
commit 54718b3a7b
26 changed files with 329 additions and 109 deletions

View File

@ -7,7 +7,13 @@ export default class Dater extends React.Component{
super(props);
}
formatDuration( milliseconds = false ){
/**
* Format time duration
*
* @param milliseconds int
* @return string (HH:mm:ss)
**/
durationTime( milliseconds = false ){
if( !milliseconds ) return null
var string = '';
@ -34,6 +40,28 @@ export default class Dater extends React.Component{
return string
}
/**
* Format time duration as a human-friendly sentence
*
* @param milliseconds int
* @return string (eg 2+ hours)
**/
durationSentence( milliseconds = false ){
if( !milliseconds ) return null
var string = '';
var total_hours, total_minutes, total_seconds, minutes, seconds;
// get total values for each
total_seconds = Math.floor( milliseconds / 1000 )
total_minutes = Math.floor( milliseconds / (1000 * 60) )
total_hours = Math.floor(milliseconds / (1000 * 60 * 60))
if( total_hours > 1 ) return total_hours+'+ hrs'
if( total_minutes > 1 ) return total_minutes+' mins'
if( total_seconds ) return total_seconds+' sec'
}
calculate(){
switch(this.props.type){
@ -44,11 +72,11 @@ export default class Dater extends React.Component{
if( tracks[i].duration_ms ) duration += parseInt(tracks[i].duration_ms);
if( tracks[i].length ) duration += parseInt(tracks[i].length);
}
return this.formatDuration(duration)
return this.durationSentence(duration)
break
case 'length':
return this.formatDuration(this.props.data)
return this.durationTime(this.props.data)
break
case 'date':

View File

@ -16,11 +16,13 @@ export default class Parallax extends React.Component{
height: 0
},
image: {},
loaded: false
loaded: false,
url: false
}
// we need to manually bind this as eventListener doesn't work with anonymous functions
this.handleResize = this.handleResize.bind(this);
this.handleScroll = this.handleScroll.bind(this);
}
componentDidMount(){
@ -28,22 +30,33 @@ export default class Parallax extends React.Component{
this.loadImage( url )
.then(
response => {
this.setState({ image: response, loaded: true })
this.setState({ url: url, image: response, loaded: true })
this.updateCanvas( response )
}
)
window.addEventListener("resize", this.handleResize);
window.addEventListener("scroll", this.handleScroll);
}
componentWillUnmount() {
componentWillUnmount(){
window.removeEventListener("resize", this.handleResize);
window.removeEventListener("scroll", this.handleScroll);
}
handleResize(){
handleResize(e){
this.updateCanvas( this.state.image );
}
handleScroll(e){
// this DOES work, but is in no way high-performing
this.setState(
{ scrollTop: e.pageY },
this.updateCanvas( this.state.image )
)
}
loadImage( url ){
return new Promise( (resolve, reject) => {

View File

@ -77,12 +77,15 @@ class Player extends React.Component{
renderFullPlayer(){
var mopidy_track = false;
if( typeof(this.props.mopidy.current_tltrack) !== 'undefined' && typeof(this.props.mopidy.current_tltrack.track) !== 'undefined' ) mopidy_track = this.props.mopidy.current_tltrack;
var images = [];
if( typeof(this.props.mopidy.current_tltrack) !== 'undefined' && typeof(this.props.mopidy.current_tltrack.track) !== 'undefined' ){
mopidy_track = this.props.mopidy.current_tltrack;
}
return (
<div className="player">
{ this.props.spotify.track && !this.props.mini ? <Link className="artwork" to={'/album/'+this.props.spotify.track.album.uri}><Thumbnail size="huge" images={this.props.spotify.track.album.images} /></Link> : null }
{ this.props.spotify.track && !this.props.mini ? <Link className="artwork" to={'/album/'+this.props.spotify.track.album.uri}><Thumbnail size="huge" images={this.props.spotify.track.album.images} /></Link> : <Link className="artwork"><Thumbnail size="huge" images={[]} /></Link> }
<div className="controls cf">
<div className="pull-left">

View File

@ -56,7 +56,7 @@ class Artist extends React.Component{
return (
<div className="view artist-view">
<Parallax images={ artist.images } />
<Parallax images={artist.images} />
<div className="intro">
<Thumbnail size="huge" images={ artist.images } />

View File

@ -65,27 +65,37 @@ class Search extends React.Component{
render(){
return (
<div className="view search-view">
<Header
icon="search"
title="Search results"
/>
<div className="cf">
<div className="col w33">
<h4>Artists</h4>
<ArtistGrid className="mini" artists={ this.compiledArtists() } />
</div>
<div className="col w33">
<h4 >Albums</h4>
<AlbumGrid className="mini" albums={ this.compiledAlbums() } />
</div>
<div className="col w33">
<h4>Playlists</h4>
<PlaylistGrid className="mini" playlists={ this.compiledPlaylists() } />
</div>
<div className="search-result-sections cf">
<section>
<div className="inner">
<h4>Artists</h4>
<ArtistGrid className="mini" artists={ this.compiledArtists() } />
</div>
</section>
<section>
<div className="inner">
<h4 >Albums</h4>
<AlbumGrid className="mini" albums={ this.compiledAlbums() } />
</div>
</section>
<section>
<div className="inner">
<h4>Playlists</h4>
<PlaylistGrid className="mini" playlists={ this.compiledPlaylists() } />
</div>
</section>
</div>
<TrackList tracks={ this.compiledTracks() } />
<section className="list-wrapper">
<TrackList tracks={ this.compiledTracks() } />
</section>
</div>
);
}

View File

@ -23,7 +23,9 @@ class DiscoverCategories extends React.Component{
return (
<div className="view discover-categories-view">
<Header icon="grid" title="Genre / Mood" />
{ this.props.spotify.categories ? <CategoryGrid categories={this.props.spotify.categories.items} /> : null }
<section className="grid-wrapper">
{ this.props.spotify.categories ? <CategoryGrid categories={this.props.spotify.categories.items} /> : null }
</section>
</div>
);
}

View File

@ -38,7 +38,9 @@ class DiscoverCategory extends React.Component{
return (
<div className="view discover-categories-view">
<Header icon="grid" title={this.props.spotify.category.name} />
{ this.props.spotify.category_playlists ? <PlaylistGrid playlists={this.props.spotify.category_playlists.items} /> : null }
<section className="grid-wrapper">
{ this.props.spotify.category_playlists ? <PlaylistGrid playlists={this.props.spotify.category_playlists.items} /> : null }
</section>
<LazyLoadListener loadMore={ () => this.loadMore() }/>
</div>
);

View File

@ -23,7 +23,9 @@ class DiscoverFeatured extends React.Component{
return (
<div className="view discover-featured-view">
<Header icon="star" title="Featured playlists" />
{ this.props.spotify.featured_playlists ? <PlaylistGrid playlists={this.props.spotify.featured_playlists.playlists.items} /> : null }
<section className="grid-wrapper">
{ this.props.spotify.featured_playlists ? <PlaylistGrid playlists={this.props.spotify.featured_playlists.playlists.items} /> : null }
</section>
</div>
);
}

View File

@ -29,7 +29,9 @@ class DiscoverNewReleases extends React.Component{
return (
<div className="view discover-new-releases-view">
<Header icon="leaf" title="New Releases" />
{ this.props.spotify.new_releases ? <AlbumGrid albums={this.props.spotify.new_releases.items} /> : null }
<section className="grid-wrapper">
{ this.props.spotify.new_releases ? <AlbumGrid albums={this.props.spotify.new_releases.items} /> : null }
</section>
<LazyLoadListener loadMore={ () => this.loadMore() }/>
</div>
);

View File

@ -33,7 +33,9 @@ class LibraryAlbums extends React.Component{
icon="cd"
title="My albums"
/>
{ this.props.spotify.library_albums ? <AlbumGrid albums={this.props.spotify.library_albums.items} /> : null }
<section className="grid-wrapper">
{ this.props.spotify.library_albums ? <AlbumGrid albums={this.props.spotify.library_albums.items} /> : null }
</section>
<LazyLoadListener loadMore={ () => this.loadMore() }/>
</div>
);

View File

@ -34,7 +34,9 @@ class LibraryArtists extends React.Component{
icon="mic"
title="My artists"
/>
{ this.props.spotify.library_artists ? <ArtistGrid artists={this.props.spotify.library_artists.items} /> : null }
<section className="grid-wrapper">
{ this.props.spotify.library_artists ? <ArtistGrid artists={this.props.spotify.library_artists.items} /> : null }
</section>
<LazyLoadListener loadMore={ () => this.loadMore() }/>
</div>
);

View File

@ -36,15 +36,17 @@ export default class LibraryLocal extends React.Component{
return (
<div className="view library-local-view">
<Header icon="folder" title="Local" />
<div className="grid category-grid">
{
grid_items.map(
(item, index) => {
return <GridItem item={item} key={index} link={item.link} />
}
)
}
</div>
<section className="grid-wrapper">
<div className="grid category-grid">
{
grid_items.map(
(item, index) => {
return <GridItem item={item} key={index} link={item.link} />
}
)
}
</div>
</section>
</div>
);
}

View File

@ -38,9 +38,9 @@ class LibraryLocalArtists extends React.Component{
return (
<div className="view library-local-view">
<Header icon="music" title="Local artists" />
<div>
<section className="list-wrapper">
<List columns={[{ name: 'name', width: '100'}]} rows={this.props.mopidy.artists} link_prefix="/artist/" />
</div>
</section>
</div>
);
}

View File

@ -46,9 +46,9 @@ class LibraryLocalDirectory extends React.Component{
return (
<div className="view library-local-view">
<Header icon="music" title="Local files" />
<div>
<section className="list-wrapper">
<List columns={[{ name: 'name', width: '100'}]} rows={this.props.mopidy.directory} link_prefix="/library/local/directory/" />
</div>
</section>
</div>
);
}

View File

@ -68,7 +68,9 @@ class LibraryPlaylists extends React.Component{
icon="playlist"
title="My playlists"
/>
{ this.renderPlaylists() }
<section className="list-wrapper">
{ this.renderPlaylists() }
</section>
</div>
)
}

View File

@ -25,7 +25,9 @@ class LibraryTracks extends React.Component{
return (
<div className="view library-tracks-view">
<Header icon="music" title="My tracks" />
{ this.props.spotify.library_tracks ? <TrackList tracks={this.props.spotify.library_tracks.items} /> : null }
<section className="list-wrapper">
{ this.props.spotify.library_tracks ? <TrackList tracks={this.props.spotify.library_tracks.items} /> : null }
</section>
</div>
);
}

View File

@ -22,4 +22,5 @@
@import 'views/album';
@import 'views/playlist';
@import 'views/queue';
@import 'views/search';

View File

@ -8,8 +8,6 @@
.grid {
padding: 40px 20px;
.grid-item {
@include grid_item( 5 )
margin: 0 2% 3%;

View File

@ -1,5 +1,7 @@
.search-form {
z-index: 2;
position: relative;
input {
background: transparent;

View File

@ -19,7 +19,7 @@ aside{
height: auto;
width: auto;
max-width: none;
z-index: -1;
z-index: 1;
opacity: 0.2;
.image {
@ -30,6 +30,8 @@ aside{
}
nav {
z-index: 2;
position: relative;
padding-top: 20px;
a {
@ -82,6 +84,7 @@ aside{
bottom: 0;
left: 0;
right: 0;
z-index: 2;
padding: 14px;
color: #FFFFFF;

View File

@ -32,8 +32,12 @@ main {
}
}
section {
padding: 40px;
section.grid-wrapper {
padding: 40px 20px;
}
section.list-wrapper {
padding: 20px 0;
}
h1 {

14
src/scss/views/_search.scss Executable file
View File

@ -0,0 +1,14 @@
.search-view {
.search-result-sections {
padding: 0 10px;
section {
width: 33.3334%;
float: left;
.inner {
padding: 10px;
}
}
}
}