From 5d0c365943df4ea858eb36b64799b96c6a0808f9 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Fri, 16 Jun 2017 20:05:32 +1200 Subject: [PATCH 01/23] Experimentation --- src/index.html | 2 +- src/js/components/Sidebar.js | 22 ++++++++--------- src/scss/components/_header.scss | 7 +++--- src/scss/components/_lists.scss | 4 +-- src/scss/components/_search-form.scss | 4 +-- src/scss/components/_sidebar.scss | 35 ++++++--------------------- src/scss/global/_core.scss | 10 +++++--- 7 files changed, 32 insertions(+), 52 deletions(-) diff --git a/src/index.html b/src/index.html index f796b4b4..74a732d8 100755 --- a/src/index.html +++ b/src/index.html @@ -14,7 +14,7 @@ - + diff --git a/src/js/components/Sidebar.js b/src/js/components/Sidebar.js index 98dc4e4c..73713108 100755 --- a/src/js/components/Sidebar.js +++ b/src/js/components/Sidebar.js @@ -32,7 +32,7 @@ class Sidebar extends React.Component{
- + Now playing
@@ -40,19 +40,19 @@ class Sidebar extends React.Component{
Discover - + Discover - + Genre / Mood - + Featured playlists - + New releases
@@ -60,30 +60,30 @@ class Sidebar extends React.Component{
My Music - + Playlists - + Artists - + Albums - + Tracks - + Local
- + Settings { !this.props.mopidy_connected || !this.props.spotify_connected || !this.props.pusher_connected ? : null } diff --git a/src/scss/components/_header.scss b/src/scss/components/_header.scss index f971187e..fd0237e8 100755 --- a/src/scss/components/_header.scss +++ b/src/scss/components/_header.scss @@ -2,20 +2,19 @@ main { header { padding: 14px 20px; - background: #EEEEEE; line-height: 24px; box-sizing: border-box; h1 { - font-size: 22px; - font-weight: 100; display: inline-block; } .icon { display: inline-block; padding-right: 14px; - height: 16px; + height: 2.5rem; + vertical-align: bottom; + margin-bottom: -5px; } .options { diff --git a/src/scss/components/_lists.scss b/src/scss/components/_lists.scss index 5f33e6db..f3310904 100755 --- a/src/scss/components/_lists.scss +++ b/src/scss/components/_lists.scss @@ -13,8 +13,8 @@ display: block; position: relative; padding: 12px 10px 12px 20px; - border-top: 1px solid $faint_grey; - border-bottom: 1px solid $faint_grey; + border-top: 1px solid $light_grey; + border-bottom: 1px solid $light_grey; margin-bottom: -1px; cursor: pointer; diff --git a/src/scss/components/_search-form.scss b/src/scss/components/_search-form.scss index 00be09d5..bb687423 100755 --- a/src/scss/components/_search-form.scss +++ b/src/scss/components/_search-form.scss @@ -5,10 +5,10 @@ input { background: transparent; - border-bottom: 1px solid #FFFFFF; + border-bottom: 1px solid $light_grey; padding: 16px 0 8px; width: 100%; - color: #FFFFFF; + color: $black; &:focus, &:active { diff --git a/src/scss/components/_sidebar.scss b/src/scss/components/_sidebar.scss index 39cee7bd..26ad6bbf 100755 --- a/src/scss/components/_sidebar.scss +++ b/src/scss/components/_sidebar.scss @@ -5,10 +5,9 @@ aside{ left: 0; bottom: 0; z-index: 96; - background: $darkest_grey; width: 220px; overflow: hidden; - box-shadow: inset -20px 0px 30px -20px rgba(0, 0, 0, 0.5); + border-right: 2px solid $light_grey; .liner { overflow-y: auto; @@ -45,25 +44,6 @@ aside{ bottom: 60px; } } - - .thumbnail { - position: absolute; - top: -30px; - right: -30px; - bottom: -30px; - left: -30px; - height: auto; - width: auto; - max-width: none; - z-index: 1; - opacity: 0.2; - - .image { - @include blur(); - padding-bottom: 0; - height: 100%; - } - } nav { z-index: 2; @@ -72,10 +52,10 @@ aside{ a { font-size: 16px; - color: #FFFFFF; + color: $black; text-decoration: none; display: block; - padding: 6px 18px 6px 14px; + padding: 6px 18px 6px 6px; border-left: 4px solid transparent; .icon { @@ -86,8 +66,7 @@ aside{ } &.active { - border-color: $turquoise; - background: rgba( 0, 0, 0, 0.5 ); + color: $turquoise; } &[disabled] { @@ -96,7 +75,7 @@ aside{ } &:hover:not([disabled]) { - background: rgba( 255, 255, 255, 0.1 ); + color: $secondary_grey; } } @@ -105,11 +84,11 @@ aside{ title { display: block; - padding: 0 18px 2px; + padding: 0 18px 2px 6px; font-size: 11px; text-transform: uppercase; opacity: 0.5; - color: #FFFFFF; + color: $mid_grey; } } diff --git a/src/scss/global/_core.scss b/src/scss/global/_core.scss index 17e78a83..1aeaad83 100755 --- a/src/scss/global/_core.scss +++ b/src/scss/global/_core.scss @@ -4,7 +4,7 @@ body, html { background: $off_white; color: #000000; - font-family: "Archivo Narrow", Helvetica, Arial, sans-serif; + font-family: "Roboto Condensed", Helvetica, Arial, sans-serif; font-size: 14px; touch-action: manipulation; } @@ -88,13 +88,15 @@ main { } h1 { - font-weight: 500; - font-size: 40px; + font-weight: 700; + font-size: 3rem; + font-family: "Montserrat"; } h2 { + font-size: 2.5rem; font-weight: 500; - font-size: 30px; + font-family: "Montserrat"; } h3 { From 911f07a806eceeb986734248c397bc8d173dc294 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Fri, 16 Jun 2017 09:37:40 +1200 Subject: [PATCH 02/23] Creating sticky playback controls in foot --- src/index.html | 2 +- src/js/App.js | 4 +- src/js/components/MiniPlayer.js | 7 + src/js/components/PlaybackControls.js | 131 ++++++++++++++++++ src/js/components/Sidebar.js | 4 - src/js/components/VolumeControl.js | 12 +- src/js/views/discover/DiscoverFeatured.js | 2 +- src/js/views/discover/DiscoverNewReleases.js | 2 +- .../views/discover/DiscoverRecommendations.js | 2 +- src/scss/app.scss | 2 +- src/scss/components/_header.scss | 5 +- src/scss/components/_playback-controls.scss | 118 ++++++++++++++++ src/scss/components/_player.scss | 16 ++- src/scss/components/_sidebar.scss | 4 +- src/scss/components/_slider.scss | 11 +- src/scss/global/_core.scss | 9 +- src/scss/views/_discover.scss | 9 +- 17 files changed, 301 insertions(+), 39 deletions(-) create mode 100755 src/js/components/PlaybackControls.js create mode 100755 src/scss/components/_playback-controls.scss diff --git a/src/index.html b/src/index.html index 74a732d8..372bcfda 100755 --- a/src/index.html +++ b/src/index.html @@ -14,7 +14,7 @@ - + diff --git a/src/js/App.js b/src/js/App.js index b0b1efe6..b1ec1c14 100755 --- a/src/js/App.js +++ b/src/js/App.js @@ -6,7 +6,7 @@ import { hashHistory, Link } from 'react-router' import { connect } from 'react-redux' import Sidebar from './components/Sidebar' -import MiniPlayer from './components/MiniPlayer' +import PlaybackControls from './components/PlaybackControls' import SidebarToggleButton from './components/SidebarToggleButton' import ContextMenu from './components/ContextMenu' import Dragger from './components/Dragger' @@ -190,7 +190,7 @@ class App extends React.Component{ return (
- +
{this.props.children}
diff --git a/src/js/components/MiniPlayer.js b/src/js/components/MiniPlayer.js index ff364cfb..d4bb7e11 100755 --- a/src/js/components/MiniPlayer.js +++ b/src/js/components/MiniPlayer.js @@ -27,8 +27,15 @@ class MiniPlayer extends React.Component{ } render(){ + var images = [] + if (this.props.current_track && this.props.current_track.album && this.props.current_track.album.images){ + images = this.props.current_track.album.images + } + return (
+ +
{ this.props.current_track ? this.props.current_track.name : - }
diff --git a/src/js/components/PlaybackControls.js b/src/js/components/PlaybackControls.js new file mode 100755 index 00000000..134a1dda --- /dev/null +++ b/src/js/components/PlaybackControls.js @@ -0,0 +1,131 @@ + +import React, { PropTypes } from 'react' +import { connect } from 'react-redux' +import { bindActionCreators } from 'redux' +import FontAwesome from 'react-fontawesome' + +import ProgressSlider from './ProgressSlider' +import VolumeControl from './VolumeControl' +import Dater from './Dater' +import ArtistSentence from './ArtistSentence' +import Thumbnail from './Thumbnail' + +import * as mopidyActions from '../services/mopidy/actions' + +class PlaybackControls extends React.Component{ + + constructor(props) { + super(props); + } + + renderPlayButton(){ + var button = this.props.mopidyActions.play()}> + if( this.props.play_state == 'playing' ){ + button = this.props.mopidyActions.pause()}> + } + return button; + } + + renderConsumeButton(){ + var button = this.props.mopidyActions.instruct('tracklist.setConsume', [true])}>Consume + if( this.props.consume ){ + button = this.props.mopidyActions.instruct('tracklist.setConsume', [false])}>Consume + } + return button; + } + + renderRandomButton(){ + var button = this.props.mopidyActions.instruct('tracklist.setRandom', [true])}>Shuffle + if( this.props.random ){ + button = this.props.mopidyActions.instruct('tracklist.setRandom', [false])}>Shuffle + } + return button; + } + + renderRepeatButton(){ + var button = this.props.mopidyActions.instruct('tracklist.setRepeat', [true])}>Repeat + if( this.props.repeat ){ + button = this.props.mopidyActions.instruct('tracklist.setRepeat', [false])}>Repeat + } + return button; + } + + render(){ + var images = [] + if (this.props.current_track && this.props.current_track.album && this.props.current_track.album.images){ + images = this.props.current_track.album.images + } + + return ( +
+ +
+ +
+ { this.props.current_track ? this.props.current_track.name : - } +
+
+ { this.props.current_track ? : } +
+
+ +
+ this.props.mopidyActions.previous()}> + + + { this.renderPlayButton() } + this.props.mopidyActions.stop()}> + + + this.props.mopidyActions.next()}> + + +
+ +
+ { this.renderConsumeButton() } + { this.renderRandomButton() } + { this.renderRepeatButton() } +
+ +
+ + { this.props.time_position ? : '-' } + { this.props.current_track ? : '-' } +
+ +
+ +
+ +
+ ); + } +} + + +/** + * Export our component + * + * We also integrate our global store, using connect() + **/ + +const mapStateToProps = (state, ownProps) => { + return { + current_track: (typeof(state.ui.current_track) !== 'undefined' && typeof(state.ui.tracks) !== 'undefined' && typeof(state.ui.tracks[state.ui.current_track.uri]) !== 'undefined' ? state.ui.tracks[state.ui.current_track.uri] : null), + radio_enabled: (state.ui.radio && state.ui.radio.enabled ? true : false), + play_state: state.mopidy.play_state, + time_position: state.mopidy.time_position, + consume: state.mopidy.consume, + repeat: state.mopidy.repeat, + random: state.mopidy.random + } +} + +const mapDispatchToProps = (dispatch) => { + return { + mopidyActions: bindActionCreators(mopidyActions, dispatch) + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(PlaybackControls) \ No newline at end of file diff --git a/src/js/components/Sidebar.js b/src/js/components/Sidebar.js index 73713108..e4ccf552 100755 --- a/src/js/components/Sidebar.js +++ b/src/js/components/Sidebar.js @@ -5,7 +5,6 @@ import { bindActionCreators } from 'redux' import { Link } from 'react-router' import Icon from './Icon' -import Thumbnail from './Thumbnail' import SearchForm from './SearchForm' import Dropzones from './Dropzones' @@ -21,8 +20,6 @@ class Sidebar extends React.Component{ render(){ return (