Album view
This commit is contained in:
@ -15,7 +15,7 @@ class SpotifyAuthenticationFrame extends React.Component{
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
frameUrl: '//jamesbarnsley.co.nz/spotmop.php?action=frame',
|
||||
frameUrl: '//jamesbarnsley.co.nz/auth.php?action=frame',
|
||||
authorizing: false
|
||||
}
|
||||
}
|
||||
@ -27,26 +27,34 @@ class SpotifyAuthenticationFrame extends React.Component{
|
||||
// listen for incoming messages from the authorization iframe
|
||||
// this is triggered when authentication is granted from the popup
|
||||
window.addEventListener('message', function(event){
|
||||
|
||||
// only allow incoming data from our authorized authenticator proxy
|
||||
if( !/^https?:\/\/jamesbarnsley\.co\.nz/.test(event.origin) ) return false;
|
||||
|
||||
var data = JSON.parse(event.data);
|
||||
self.props.actions.authorizationGranted( data );
|
||||
self.props.actions.getMe();
|
||||
|
||||
// and turn off our authorizing switch
|
||||
self.setState({
|
||||
frameUrl: '//jamesbarnsley.co.nz/spotmop.php?action=frame',
|
||||
authorizing: false
|
||||
})
|
||||
if(event.data == 'closed'){
|
||||
self.setState({
|
||||
frameUrl: '//jamesbarnsley.co.nz/auth.php?action=frame',
|
||||
authorizing: false
|
||||
})
|
||||
}else{
|
||||
|
||||
// only allow incoming data from our authorized authenticator proxy
|
||||
if( !/^https?:\/\/jamesbarnsley\.co\.nz/.test(event.origin) ) return false;
|
||||
|
||||
var data = JSON.parse(event.data);
|
||||
self.props.actions.authorizationGranted( data );
|
||||
self.props.actions.getMe();
|
||||
|
||||
// and turn off our authorizing switch
|
||||
self.setState({
|
||||
frameUrl: '//jamesbarnsley.co.nz/auth.php?action=frame',
|
||||
authorizing: false
|
||||
})
|
||||
}
|
||||
|
||||
}, false);
|
||||
}
|
||||
|
||||
startAuthorization(){
|
||||
this.setState({
|
||||
frameUrl: '//jamesbarnsley.co.nz/spotmop.php?action=authorize&app='+location.protocol+'//'+window.location.host,
|
||||
frameUrl: '//jamesbarnsley.co.nz/auth.php?action=authorize&app='+location.protocol+'//'+window.location.host,
|
||||
authorizing: true
|
||||
})
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ class VersionManager extends React.Component{
|
||||
super(props);
|
||||
}
|
||||
|
||||
renderUpdateButton(){
|
||||
renderUpgradeButton(){
|
||||
if( this.props.pusher.upgrading ){
|
||||
return (
|
||||
<button disabled>
|
||||
@ -30,7 +30,7 @@ class VersionManager extends React.Component{
|
||||
}
|
||||
|
||||
if( this.props.pusher.version.upgrade_available ){
|
||||
return <button className="secondary" onClick={() => this.props.pusherActions.performUpdate()}>Update now</button>
|
||||
return <button className="secondary" onClick={() => this.props.pusherActions.performUpgrade()}>Upgrade to { this.props.pusher.version.latest }</button>
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -40,7 +40,7 @@ class VersionManager extends React.Component{
|
||||
return (
|
||||
<div className="version-manager">
|
||||
<span>{ this.props.pusher.version.current } installed</span>
|
||||
{ this.renderUpdateButton() }
|
||||
{ this.renderUpgradeButton() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -14,18 +14,6 @@ const localstorageMiddleware = (function(){
|
||||
|
||||
switch( action.type ){
|
||||
|
||||
case 'PUSHER_SET_CONFIG':
|
||||
var pusher = JSON.parse( localStorage.getItem('pusher') );
|
||||
if( !pusher ) pusher = {};
|
||||
Object.assign(
|
||||
pusher,{
|
||||
username: action.config.username,
|
||||
port: action.config.port
|
||||
}
|
||||
);
|
||||
localStorage.setItem('pusher', JSON.stringify(pusher));
|
||||
break;
|
||||
|
||||
case 'PUSHER_CONNECTED':
|
||||
var pusher = JSON.parse( localStorage.getItem('pusher') );
|
||||
if( !pusher ) pusher = {};
|
||||
@ -38,6 +26,13 @@ const localstorageMiddleware = (function(){
|
||||
localStorage.setItem('pusher', JSON.stringify(pusher));
|
||||
break;
|
||||
|
||||
case 'PUSHER_SET_PORT':
|
||||
var pusher = JSON.parse( localStorage.getItem('pusher') );
|
||||
if( !pusher ) pusher = {};
|
||||
Object.assign( pusher, { port: action.port } );
|
||||
localStorage.setItem('pusher', JSON.stringify(pusher));
|
||||
break;
|
||||
|
||||
case 'PUSHER_CHANGE_USERNAME':
|
||||
var pusher = JSON.parse( localStorage.getItem('pusher') );
|
||||
if( !pusher ) pusher = {};
|
||||
|
||||
@ -3,10 +3,10 @@
|
||||
* Actions and Action Creators
|
||||
**/
|
||||
|
||||
export function setConfig( config ){
|
||||
export function setPort( port ){
|
||||
return {
|
||||
type: 'PUSHER_SET_CONFIG',
|
||||
config: config
|
||||
type: 'PUSHER_SET_PORT',
|
||||
port: port
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -13,10 +13,8 @@ export default function reducer(pusher = {}, action){
|
||||
case 'PUSHER_DISCONNECTED':
|
||||
return Object.assign({}, pusher, { connected: false, connecting: false });
|
||||
|
||||
case 'PUSHER_SET_CONFIG':
|
||||
return Object.assign({}, pusher, {
|
||||
port: action.port
|
||||
});
|
||||
case 'PUSHER_SET_PORT':
|
||||
return Object.assign({}, pusher, { port: action.port });
|
||||
|
||||
case 'PUSHER_CHANGE_USERNAME':
|
||||
return Object.assign({}, pusher, { username: action.data.connection.username });
|
||||
|
||||
@ -104,11 +104,9 @@ function refreshToken( dispatch, getState ){
|
||||
|
||||
if( getState().spotify.authorized ){
|
||||
|
||||
console.log('Refreshing token as '+getState().spotify.expires_in+' older than '+new Date().getTime())
|
||||
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: '//jamesbarnsley.co.nz/spotmop.php?action=refresh&refresh_token='+getState().spotify.refresh_token,
|
||||
url: '//jamesbarnsley.co.nz/auth.php?action=refresh&refresh_token='+getState().spotify.refresh_token,
|
||||
dataType: "json",
|
||||
timeout: 10000
|
||||
})
|
||||
|
||||
@ -4,7 +4,9 @@ import { connect } from 'react-redux'
|
||||
import { bindActionCreators } from 'redux'
|
||||
|
||||
import TrackList from '../components/TrackList'
|
||||
import Header from '../components/Header'
|
||||
import Thumbnail from '../components/Thumbnail'
|
||||
import Parallax from '../components/Parallax'
|
||||
import ArtistSentence from '../components/ArtistSentence'
|
||||
|
||||
import * as spotifyActions from '../services/spotify/actions'
|
||||
import * as mopidyActions from '../services/mopidy/actions'
|
||||
@ -31,11 +33,14 @@ class Album extends React.Component{
|
||||
if( this.props.spotify.album ){
|
||||
return (
|
||||
<div className="view album-view">
|
||||
<Header
|
||||
icon="cd"
|
||||
title={ this.props.spotify.album.name }
|
||||
/>
|
||||
<TrackList tracks={this.props.spotify.album.tracks.items} />
|
||||
<div className="intro">
|
||||
<Thumbnail size="large" images={ this.props.spotify.album.images } />
|
||||
</div>
|
||||
<div className="main">
|
||||
<h1>{ this.props.spotify.album.name }</h1>
|
||||
<h3><ArtistSentence artists={ this.props.spotify.album.artists } /></h3>
|
||||
<TrackList tracks={this.props.spotify.album.tracks.items} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -77,6 +77,9 @@ class App extends React.Component{
|
||||
<main>
|
||||
{this.props.children}
|
||||
</main>
|
||||
<footer>
|
||||
Iris by James Barnsley | v{ this.props.pusher.version.current }
|
||||
</footer>
|
||||
{ this.props.ui.context_menu.test }
|
||||
<ContextMenu state={this.props.ui.context_menu} />
|
||||
</div>
|
||||
|
||||
@ -41,13 +41,6 @@ class Settings extends React.Component{
|
||||
return false;
|
||||
}
|
||||
|
||||
setPusherConfig(e){
|
||||
e.preventDefault();
|
||||
this.props.pusherActions.changeUsername( this.state.pusher_username );
|
||||
this.props.pusherActions.setConfig({ port: this.state.pusher_port });
|
||||
return false;
|
||||
}
|
||||
|
||||
setSpotifyConfig(e){
|
||||
e.preventDefault();
|
||||
this.props.spotifyActions.setConfig({ country: this.state.spotify_country, locale: this.state.spotify_locale });
|
||||
@ -96,13 +89,14 @@ class Settings extends React.Component{
|
||||
</form>
|
||||
|
||||
<h3 className="underline">Pusher</h3>
|
||||
<form onSubmit={(e) => this.setPusherConfig(e)}>
|
||||
<form>
|
||||
<label>
|
||||
<div className="label">Username</div>
|
||||
<div className="input">
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ pusher_username: e.target.value })}
|
||||
onChange={ e => this.setState({ pusher_username: e.target.value }) }
|
||||
onBlur={ e => this.props.pusherActions.changeUsername( this.state.pusher_username ) }
|
||||
value={ this.state.pusher_username } />
|
||||
</div>
|
||||
</label>
|
||||
@ -112,10 +106,10 @@ class Settings extends React.Component{
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ pusher_port: e.target.value })}
|
||||
onBlur={ e => this.props.pusherActions.setPort({ port: this.state.pusher_port }) }
|
||||
value={ this.state.pusher_port } />
|
||||
</div>
|
||||
</label>
|
||||
<button type="submit" className="secondary">Apply</button>
|
||||
</form>
|
||||
|
||||
<h3 className="underline">Spotify</h3>
|
||||
@ -126,6 +120,7 @@ class Settings extends React.Component{
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ spotify_country: e.target.value })}
|
||||
onBlur={ e => this.setSpotifyConfig(e) }
|
||||
value={ this.state.spotify_country } />
|
||||
</div>
|
||||
</label>
|
||||
@ -135,10 +130,10 @@ class Settings extends React.Component{
|
||||
<input
|
||||
type="text"
|
||||
onChange={ e => this.setState({ spotify_locale: e.target.value })}
|
||||
onBlur={ e => this.setSpotifyConfig(e) }
|
||||
value={ this.state.spotify_locale } />
|
||||
</div>
|
||||
</label>
|
||||
<button type="submit" className="secondary">Apply</button>
|
||||
</form>
|
||||
|
||||
<SpotifyAuthenticationFrame />
|
||||
|
||||
@ -16,4 +16,5 @@
|
||||
@import 'components/header';
|
||||
|
||||
@import 'views/artist';
|
||||
@import 'views/album';
|
||||
|
||||
|
||||
@ -13,9 +13,14 @@ body {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
main {
|
||||
main,
|
||||
footer {
|
||||
margin-left: 200px;
|
||||
}
|
||||
|
||||
padding-left: 200px;
|
||||
main {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
@ -32,8 +37,8 @@ main {
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 100;
|
||||
font-size: 26px;
|
||||
font-weight: 500;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
@ -99,4 +104,12 @@ main {
|
||||
|
||||
.grey-text {
|
||||
color: $mid_grey;
|
||||
}
|
||||
|
||||
footer {
|
||||
display: block;
|
||||
color: $light_grey;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
24
src/scss/views/_album.scss
Executable file
24
src/scss/views/_album.scss
Executable file
@ -0,0 +1,24 @@
|
||||
|
||||
.album-view {
|
||||
.intro {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 300px;
|
||||
background: $light_grey;
|
||||
|
||||
.thumbnail {
|
||||
float: none;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding-top: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
padding-left: 300px;
|
||||
}
|
||||
}
|
||||
@ -2,13 +2,18 @@
|
||||
.artist-view {
|
||||
.intro {
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
margin: -100px 0 20px 0;
|
||||
@include clearfix;
|
||||
|
||||
.thumbnail {
|
||||
max-width: 200px;
|
||||
margin: -100px 20px 0 40px;
|
||||
margin: 0 20px 0 40px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #FFFFFF;
|
||||
padding-top: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
src/scss/views/_playlist.scss
Executable file
30
src/scss/views/_playlist.scss
Executable file
@ -0,0 +1,30 @@
|
||||
|
||||
.album-view {
|
||||
.intro {
|
||||
@include clearfix;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
color: #FFFFFF;
|
||||
padding: 20px;
|
||||
height: 40vh;
|
||||
z-index: 2;
|
||||
|
||||
.parallax {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
float: none;
|
||||
margin: 0 auto;
|
||||
max-width: 160px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding-top: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user