Revamp of asset designs
This commit is contained in:
@ -31,10 +31,13 @@ class FollowButton extends React.Component{
|
||||
render(){
|
||||
if( !this.props.spotify_authorized || !this.props.uri ) return false
|
||||
|
||||
var className = 'tertiary'
|
||||
if (this.props.className) className += ' '+this.props.className
|
||||
|
||||
if( this.props.is_following === true ){
|
||||
return <button className="tertiary large" onClick={ () => this.remove() }>{ this.props.removeText }</button>
|
||||
return <button className={className} onClick={ () => this.remove() }>{ this.props.removeText }</button>
|
||||
}else{
|
||||
return <button className="tertiary large" onClick={ () => this.add() }>{ this.props.addText }</button>
|
||||
return <button className={className} onClick={ () => this.add() }>{ this.props.addText }</button>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,10 +104,9 @@ class SpotifyAuthenticationFrame extends React.Component{
|
||||
render(){
|
||||
return (
|
||||
<span>
|
||||
{ this.renderAuthorizeButton() }
|
||||
|
||||
{ this.renderRefreshButton() }
|
||||
<iframe src={this.state.frameUrl} style={{ display: 'none' }}></iframe>
|
||||
{ this.renderAuthorizeButton() }
|
||||
{ this.renderRefreshButton() }
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@ -33,15 +33,15 @@ class VersionManager extends React.Component{
|
||||
return <button className="secondary" onClick={() => this.props.pusherActions.startUpgrade()}>Upgrade to { this.props.pusher.version.latest }</button>
|
||||
}
|
||||
|
||||
return <button className="secondary" disabled>Already up to date</button>
|
||||
return <button className="secondary" disabled>No updates available</button>
|
||||
}
|
||||
|
||||
render(){
|
||||
return (
|
||||
<div className="version-manager">
|
||||
<span className="version-manager">
|
||||
{ this.renderUpgradeButton() }
|
||||
<div className="description">{ this.props.pusher.version.current } currently installed</div>
|
||||
</div>
|
||||
<span className="description">{ this.props.pusher.version.current } installed</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,13 +130,13 @@ const PusherMiddleware = (function(){
|
||||
request({ action: 'get_version' })
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({ type: 'VERSION', version: response.data.version })
|
||||
store.dispatch({ type: 'VERSION', data: response.data })
|
||||
}
|
||||
)
|
||||
request({ action: 'get_radio' })
|
||||
.then(
|
||||
response => {
|
||||
store.dispatch({ type: 'RADIO', radio: response.data.radio })
|
||||
store.dispatch({ type: 'RADIO', data: response.data })
|
||||
}
|
||||
)
|
||||
return next(action);
|
||||
@ -155,7 +155,7 @@ const PusherMiddleware = (function(){
|
||||
}else{
|
||||
store.dispatch( uiActions.createNotification('Upgrade failed, please upgrade manually','bad') )
|
||||
}
|
||||
store.dispatch({ type: 'VERSION', version: response.data.version })
|
||||
store.dispatch({ type: 'VERSION', data: response.data })
|
||||
}
|
||||
)
|
||||
return next(action);
|
||||
|
||||
@ -86,15 +86,14 @@ const SpotifyMiddleware = (function(){
|
||||
}
|
||||
break
|
||||
|
||||
// when our mopidy server current track changes
|
||||
// when radio returns
|
||||
case 'RADIO':
|
||||
|
||||
// proceed as usual so we don't inhibit default functionality
|
||||
next(action)
|
||||
|
||||
// only resolve if radio is enabled
|
||||
if( action.radio.enabled ){
|
||||
store.dispatch(spotifyActions.resolveRadioSeeds(action.radio))
|
||||
if( action.data.radio.enabled ){
|
||||
store.dispatch(spotifyActions.resolveRadioSeeds(action.data.radio))
|
||||
}
|
||||
break
|
||||
|
||||
|
||||
@ -210,8 +210,8 @@ const UIMiddleware = (function(){
|
||||
break
|
||||
|
||||
case 'VERSION':
|
||||
if( action.version.upgrade_available )
|
||||
store.dispatch( uiActions.createNotification( 'Version '+action.version.latest+' is available. See settings to upgrade.' ) )
|
||||
if( action.data.version.upgrade_available )
|
||||
store.dispatch( uiActions.createNotification( 'Version '+action.data.version.latest+' is available. See settings to upgrade.' ) )
|
||||
next( action )
|
||||
break
|
||||
|
||||
|
||||
@ -121,7 +121,7 @@ export default function reducer(ui = {}, action){
|
||||
|
||||
case 'RADIO':
|
||||
case 'START_RADIO':
|
||||
return Object.assign({}, ui, { seeds_resolved: false }, { radio: action.radio })
|
||||
return Object.assign({}, ui, { seeds_resolved: false }, { radio: action.data.radio })
|
||||
|
||||
case 'RADIO_SEEDS_RESOLVED':
|
||||
var radio = Object.assign({}, ui.radio, { resolved_seeds: action.resolved_seeds })
|
||||
|
||||
@ -84,12 +84,6 @@ class Artist extends React.Component{
|
||||
this.props.spotifyActions.getURL( this.props.artist.albums_more, 'SPOTIFY_ARTIST_ALBUMS_LOADED', this.props.params.uri );
|
||||
}
|
||||
|
||||
play(){
|
||||
if (!this.props.artist.uri) return
|
||||
this.props.uiActions.createNotification('Starting radio...')
|
||||
this.props.pusherActions.startRadio([this.props.artist.uri])
|
||||
}
|
||||
|
||||
renderSubViewMenu(){
|
||||
return (
|
||||
<div className="sub-views">
|
||||
@ -105,6 +99,8 @@ class Artist extends React.Component{
|
||||
}
|
||||
|
||||
renderBody(){
|
||||
var scheme = helpers.uriSource( this.props.params.uri );
|
||||
|
||||
var related_artists = []
|
||||
if (this.props.artist.related_artists_uris){
|
||||
for (var i = 0; i < this.props.artist.related_artists_uris.length; i++){
|
||||
@ -138,6 +134,17 @@ class Artist extends React.Component{
|
||||
return (
|
||||
<div className="body biography">
|
||||
<h4 className="left-padding">Biography</h4>
|
||||
|
||||
<ul className="details">
|
||||
<li>
|
||||
{ this.props.artist.followers ? <span>{ this.props.artist.followers.total.toLocaleString() } followers, </span> : null }
|
||||
{ this.props.artist.popularity ? <span>{ this.props.artist.popularity }% popularity</span> : null }
|
||||
{ this.props.artist.listeners && scheme == 'local' ? <span>{ this.props.artist.listeners.toLocaleString() } listeners</span> : null }
|
||||
</li>
|
||||
{ scheme == 'spotify' ? <li><FontAwesome name='spotify' /> Spotify artist</li> : null }
|
||||
{ scheme == 'local' ? <li><FontAwesome name='folder' /> Local artist</li> : null }
|
||||
</ul>
|
||||
|
||||
<section className="text-wrapper no-top-padding">
|
||||
{ this.props.artist.bio ? <div><p>{this.props.artist.bio.content}</p><br />
|
||||
<div className="grey-text">Published: { this.props.artist.bio.published }</div>
|
||||
@ -183,33 +190,15 @@ class Artist extends React.Component{
|
||||
|
||||
<div className="intro">
|
||||
|
||||
<Thumbnail canZoom image={ image } />
|
||||
<Parallax image={ image } />
|
||||
|
||||
<div className="heading-wrapper">
|
||||
<div className="heading">
|
||||
<h1>{ this.props.artist.name }</h1>
|
||||
{ this.renderSubViewMenu() }
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="details-wrapper">
|
||||
|
||||
<div className="liner">
|
||||
<h1>{ this.props.artist.name }</h1>
|
||||
<div className="actions">
|
||||
<button className="large primary" onClick={ e => this.play() }>Start radio</button>
|
||||
{ helpers.uriSource(this.props.params.uri) == 'spotify' ? <FollowButton uri={this.props.params.uri} removeText="Unfollow" addText="Follow" is_following={this.props.artist.is_following} /> : null }
|
||||
<button className="primary rounded" onClick={e => this.props.pusherActions.startRadio([this.props.artist.uri])}>Start radio</button>
|
||||
{ scheme == 'spotify' ? <FollowButton className="rounded" uri={this.props.params.uri} removeText="Unfollow" addText="Follow" is_following={this.props.artist.is_following} /> : null }
|
||||
</div>
|
||||
|
||||
<ul className="details">
|
||||
<li>
|
||||
{ this.props.artist.followers ? <span>{ this.props.artist.followers.total.toLocaleString() } followers, </span> : null }
|
||||
{ this.props.artist.popularity ? <span>{ this.props.artist.popularity }% popularity</span> : null }
|
||||
{ this.props.artist.listeners && scheme == 'local' ? <span>{ this.props.artist.listeners.toLocaleString() } listeners</span> : null }
|
||||
</li>
|
||||
{ scheme == 'spotify' ? <li><FontAwesome name='spotify' /> Spotify artist</li> : null }
|
||||
{ scheme == 'local' ? <li><FontAwesome name='folder' /> Local artist</li> : null }
|
||||
</ul>
|
||||
|
||||
{ this.renderSubViewMenu() }
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
|
||||
import React, { PropTypes } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { Link } from 'react-router'
|
||||
import { Link, hashHistory } from 'react-router'
|
||||
import { bindActionCreators } from 'redux'
|
||||
import FontAwesome from 'react-fontawesome'
|
||||
|
||||
@ -55,9 +55,17 @@ class Debug extends React.Component{
|
||||
}
|
||||
|
||||
render(){
|
||||
|
||||
var actions = (
|
||||
<button onClick={e => hashHistory.push(global.baseURL+'settings')}>
|
||||
<FontAwesome name="cog" />
|
||||
Settings
|
||||
</button>
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="view debugger-view">
|
||||
<Header icon="cog" title="Debugger" />
|
||||
<Header icon="cog" title="Debugger" actions={actions} />
|
||||
|
||||
<section>
|
||||
|
||||
|
||||
@ -97,7 +97,7 @@ class Settings extends React.Component{
|
||||
<Thumbnail circle={true} size="small" images={user.images} />
|
||||
<span className="user-name">
|
||||
{user.display_name ? user.display_name : user.username}
|
||||
{!this.props.spotify.authorized ? <span className="grey-text"> (As defined in config file)</span> : null}
|
||||
{!this.props.spotify.authorized ? <span className="grey-text"> (limited access)</span> : null}
|
||||
</span>
|
||||
</Link>
|
||||
)
|
||||
@ -107,7 +107,7 @@ class Settings extends React.Component{
|
||||
<Thumbnail circle={true} size="small" />
|
||||
<span className="user-name">
|
||||
Default user
|
||||
<span className="grey-text"> (As defined in config file)</span>
|
||||
<span className="grey-text"> (limited access)</span>
|
||||
</span>
|
||||
</Link>
|
||||
)
|
||||
@ -127,9 +127,17 @@ class Settings extends React.Component{
|
||||
}
|
||||
|
||||
render(){
|
||||
|
||||
var actions = (
|
||||
<button onClick={e => hashHistory.push(global.baseURL+'debug')}>
|
||||
<FontAwesome name="flask" />
|
||||
Debug
|
||||
</button>
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="view settings-view">
|
||||
<Header icon="cog" title="Settings" />
|
||||
<Header icon="cog" title="Settings" actions={actions} />
|
||||
|
||||
<section>
|
||||
|
||||
@ -238,7 +246,6 @@ class Settings extends React.Component{
|
||||
<div className="name">Authentication</div>
|
||||
<div className="input">
|
||||
<SpotifyAuthenticationFrame />
|
||||
|
||||
{ this.renderSendAuthorizationButton() }
|
||||
</div>
|
||||
</div>
|
||||
@ -264,22 +271,11 @@ class Settings extends React.Component{
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<div className="name">Version</div>
|
||||
<div className="input">
|
||||
<VersionManager />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="field">
|
||||
<div className="name"></div>
|
||||
<div className="name">System</div>
|
||||
<div className="input">
|
||||
<ConfirmationButton className="destructive" content="Reset all settings" confirmingContent="Are you sure?" onConfirm={() => this.resetAllSettings()} />
|
||||
|
||||
<button className="primary" onClick={ () => hashHistory.push(global.baseURL+'debug') }>
|
||||
<FontAwesome name="flask" /> Debugger
|
||||
</button>
|
||||
</div>
|
||||
<VersionManager />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 className="underline">About</h4>
|
||||
|
||||
@ -37,6 +37,7 @@ input[type="submit"] {
|
||||
@include animate();
|
||||
padding: 10px 20px;
|
||||
border: 0;
|
||||
margin: 0 10px 5px 0;
|
||||
color: #000000;
|
||||
background: $light_grey;
|
||||
|
||||
@ -53,6 +54,14 @@ input[type="submit"] {
|
||||
}
|
||||
}
|
||||
|
||||
&.rounded {
|
||||
margin-right: 20px;
|
||||
padding: 10px 20px;
|
||||
text-align: center;
|
||||
min-width: 140px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
&.primary {
|
||||
background: $turquoise;
|
||||
color: #FFFFFF;
|
||||
|
||||
@ -12,67 +12,48 @@
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
max-width: 240px;
|
||||
bottom: 0;
|
||||
left: 40px;
|
||||
}
|
||||
|
||||
.heading-wrapper {
|
||||
height: 50vh;
|
||||
.liner {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
z-index: 1;
|
||||
padding: 15vh 40px 20px 40px;
|
||||
|
||||
.heading {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 320px;
|
||||
|
||||
h1 {
|
||||
color: #FFFFFF;
|
||||
padding-top: 30px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.sub-views {
|
||||
color: #FFFFFF;
|
||||
|
||||
.option {
|
||||
display: inline-block;
|
||||
padding: 8px 0;
|
||||
margin-right: 20px;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
border-bottom: 4px solid transparent;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
border-color: $off_white;
|
||||
}
|
||||
|
||||
&:not(.active):hover {
|
||||
border-color: rgba(255,255,255,0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
h1 {
|
||||
color: #FFFFFF;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.details-wrapper {
|
||||
padding-left: 320px;
|
||||
padding-top: 35px;
|
||||
|
||||
.actions {
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
.button {
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.details {
|
||||
padding-top: 6px;
|
||||
.sub-views {
|
||||
color: #FFFFFF;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 30px;
|
||||
|
||||
.option {
|
||||
display: inline-block;
|
||||
padding: 8px 0;
|
||||
margin: 0 10px;
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
border-bottom: 4px solid transparent;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
border-color: $off_white;
|
||||
}
|
||||
|
||||
&:not(.active):hover {
|
||||
border-color: rgba(255,255,255,0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user