Version manager for pusher; Local spotify tokens
This commit is contained in:
5
src/js/bootstrap.js
vendored
5
src/js/bootstrap.js
vendored
@ -35,7 +35,10 @@ var initialState = {
|
||||
username: '',
|
||||
connections: [],
|
||||
connected: false,
|
||||
port: 6681
|
||||
port: 6681,
|
||||
version: {
|
||||
current: '0.0.0'
|
||||
}
|
||||
},
|
||||
spotify: {
|
||||
connected: false,
|
||||
|
||||
@ -38,9 +38,11 @@ class PusherConnectionList extends React.Component{
|
||||
if( connection.connectionid == this.props.pusher.connectionid ) isMe = true;
|
||||
return (
|
||||
<div className="connection cf" key={connection.connectionid}>
|
||||
<div className="col w20">{ connection.username } { isMe ? <span>(you)</span> : null }</div>
|
||||
<div className="col w20 one-liner">{ connection.ip }</div>
|
||||
<div className="col w20 one-liner">{ connection.connectionid }</div>
|
||||
<div className="col w30">{ connection.username } { isMe ? <span>(you)</span> : null }</div>
|
||||
<div className="col w70">
|
||||
{ connection.ip }
|
||||
<span className="grey-text"> ({ connection.connectionid })</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
|
||||
@ -17,10 +17,6 @@ class Sidebar extends React.Component{
|
||||
super(props);
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
console.log( this.props )
|
||||
}
|
||||
|
||||
render(){
|
||||
return (
|
||||
<aside>
|
||||
@ -62,15 +58,15 @@ class Sidebar extends React.Component{
|
||||
<Icon name="playlist" className="white" />
|
||||
Playlists
|
||||
</Link>
|
||||
<Link activeClassName="active" to="/library/artists">
|
||||
<Link activeClassName="active" disabled={!this.props.spotify.authorized} to="/library/artists">
|
||||
<Icon name="mic" className="white" />
|
||||
Artists
|
||||
</Link>
|
||||
<Link activeClassName="active" to="/library/albums">
|
||||
<Link activeClassName="active" disabled={!this.props.spotify.authorized} to="/library/albums">
|
||||
<Icon name="cd" className="white" />
|
||||
Albums
|
||||
</Link>
|
||||
<Link activeClassName="active" to="/library/tracks">
|
||||
<Link activeClassName="active" disabled={!this.props.spotify.authorized} to="/library/tracks">
|
||||
<Icon name="music" className="white" />
|
||||
Tracks
|
||||
</Link>
|
||||
|
||||
59
src/js/components/VersionManager.js
Executable file
59
src/js/components/VersionManager.js
Executable file
@ -0,0 +1,59 @@
|
||||
|
||||
import React, { PropTypes } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { Link } from 'react-router'
|
||||
import { createStore, bindActionCreators } from 'redux'
|
||||
|
||||
import FontAwesome from 'react-fontawesome'
|
||||
|
||||
import * as pusherActions from '../services/pusher/actions'
|
||||
|
||||
class VersionManager extends React.Component{
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
renderUpdateButton(){
|
||||
if( this.props.pusher.upgrading ){
|
||||
return (
|
||||
<button disabled>
|
||||
<FontAwesome name="circle-o-notch" spin />
|
||||
|
||||
Upgrading
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
if( !this.props.pusher.version.is_root ){
|
||||
return <button className="secondary" disabled>Cannot upgrade</button>
|
||||
}
|
||||
|
||||
if( this.props.pusher.version.upgrade_available ){
|
||||
return <button className="secondary" onClick={() => this.props.pusherActions.performUpdate()}>Update now</button>
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
render(){
|
||||
return (
|
||||
<div className="version-manager">
|
||||
<span>{ this.props.pusher.version.current } installed</span>
|
||||
{ this.renderUpdateButton() }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
return state;
|
||||
}
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return {
|
||||
pusherActions: bindActionCreators(pusherActions, dispatch)
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(VersionManager)
|
||||
@ -30,6 +30,12 @@ export function disconnect(){
|
||||
}
|
||||
}
|
||||
|
||||
export function performUpgrade(){
|
||||
return {
|
||||
type: 'PUSHER_UPGRADING'
|
||||
}
|
||||
}
|
||||
|
||||
export function getConnectionList(){
|
||||
return {
|
||||
type: 'PUSHER_INSTRUCT',
|
||||
|
||||
@ -66,6 +66,12 @@ const PusherMiddleware = (function(){
|
||||
|
||||
case 'PUSHER_CONNECTED':
|
||||
makeRequest({ action: 'get_version' });
|
||||
makeRequest({ action: 'get_spotify_token' });
|
||||
return next(action);
|
||||
break;
|
||||
|
||||
case 'PUSHER_UPGRADING':
|
||||
makeRequest({ action: 'perform_upgrade' });
|
||||
return next(action);
|
||||
break;
|
||||
|
||||
|
||||
@ -36,7 +36,13 @@ export default function reducer(pusher = {}, action){
|
||||
return Object.assign({}, pusher, { connections: action.data.connections });
|
||||
|
||||
case 'PUSHER_VERSION':
|
||||
return Object.assign({}, pusher, { version: action.data });
|
||||
return Object.assign({}, pusher, {
|
||||
version: action.data.version,
|
||||
upgrading: false
|
||||
});
|
||||
|
||||
case 'PUSHER_UPGRADING':
|
||||
return Object.assign({}, pusher, { upgrading: true });
|
||||
|
||||
default:
|
||||
return pusher
|
||||
|
||||
@ -101,26 +101,56 @@ function getToken( dispatch, getState ){
|
||||
|
||||
function refreshToken( dispatch, getState ){
|
||||
return new Promise( (resolve, reject) => {
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: '//jamesbarnsley.co.nz/spotmop.php?action=refresh&refresh_token='+getState().spotify.refresh_token,
|
||||
dataType: "json",
|
||||
timeout: 10000
|
||||
})
|
||||
.then(
|
||||
response => {
|
||||
response.token_expiry = new Date().getTime() + ( response.expires_in * 1000 );
|
||||
dispatch({
|
||||
type: 'SPOTIFY_TOKEN_REFRESHED',
|
||||
data: response
|
||||
});
|
||||
resolve(response);
|
||||
},
|
||||
error => {
|
||||
console.error('Could not refresh token', error)
|
||||
reject(error)
|
||||
}
|
||||
);
|
||||
|
||||
if( getState().spotify.authorized ){
|
||||
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: '//jamesbarnsley.co.nz/spotmop.php?action=refresh&refresh_token='+getState().spotify.refresh_token,
|
||||
dataType: "json",
|
||||
timeout: 10000
|
||||
})
|
||||
.then(
|
||||
response => {
|
||||
response.token_expiry = new Date().getTime() + ( response.expires_in * 1000 );
|
||||
response.source = 'spotify';
|
||||
dispatch({
|
||||
type: 'SPOTIFY_TOKEN_REFRESHED',
|
||||
data: response
|
||||
});
|
||||
resolve(response);
|
||||
},
|
||||
error => {
|
||||
console.error('Could not refresh token', error)
|
||||
reject(error)
|
||||
}
|
||||
);
|
||||
|
||||
}else{
|
||||
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: '//'+getState().mopidy.host+':'+getState().mopidy.port+'/spotmop/http?action=refresh_spotify_token',
|
||||
dataType: "json",
|
||||
timeout: 10000
|
||||
})
|
||||
.then(
|
||||
response => {
|
||||
response.token_expiry = new Date().getTime() + ( response.expires_in * 1000 );
|
||||
response.source = 'mopidy';
|
||||
dispatch({
|
||||
type: 'SPOTIFY_TOKEN_REFRESHED',
|
||||
data: response
|
||||
});
|
||||
resolve(response);
|
||||
},
|
||||
error => {
|
||||
console.error('Could not refresh token', error)
|
||||
reject(error)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,16 @@ export default function reducer(spotify = {}, action){
|
||||
token_expiry: action.data.token_expiry
|
||||
});
|
||||
|
||||
case 'PUSHER_SPOTIFY_TOKEN':
|
||||
if( spotify.authorized ) return spotify;
|
||||
return Object.assign({}, spotify, {
|
||||
authorizing: false,
|
||||
authorized: false,
|
||||
authorization: false,
|
||||
access_token: action.data.access_token,
|
||||
token_expiry: action.data.token_expiry
|
||||
});
|
||||
|
||||
case 'SPOTIFY_AUTHORIZATION_REVOKED':
|
||||
return Object.assign({}, spotify, {
|
||||
authorizing: false,
|
||||
|
||||
@ -7,6 +7,7 @@ import FontAwesome from 'react-fontawesome'
|
||||
import SpotifyAuthenticationFrame from '../components/SpotifyAuthenticationFrame'
|
||||
import ConfirmationButton from '../components/ConfirmationButton'
|
||||
import PusherConnectionList from '../components/PusherConnectionList'
|
||||
import VersionManager from '../components/VersionManager'
|
||||
import Header from '../components/Header'
|
||||
|
||||
import * as pusherActions from '../services/pusher/actions'
|
||||
@ -142,9 +143,13 @@ class Settings extends React.Component{
|
||||
|
||||
<SpotifyAuthenticationFrame />
|
||||
|
||||
<ConfirmationButton content="Reset all settings" confirmingContent="Are you sure?" onConfirm={() => this.resetAllSettings()} />
|
||||
|
||||
<h3 className="underline">Advanced</h3>
|
||||
<label>
|
||||
<div className="label">Version</div>
|
||||
<div className="input">
|
||||
<VersionManager />
|
||||
</div>
|
||||
</label>
|
||||
<label>
|
||||
<div className="label">Connections</div>
|
||||
<div className="input">
|
||||
@ -152,6 +157,8 @@ class Settings extends React.Component{
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<ConfirmationButton content="Reset all settings" confirmingContent="Are you sure?" onConfirm={() => this.resetAllSettings()} />
|
||||
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -18,16 +18,21 @@ class LibraryPlaylists extends React.Component{
|
||||
|
||||
// on render
|
||||
componentDidMount(){
|
||||
if( this.props.mopidy.connected ) this.loadPlaylists();
|
||||
if( this.props.mopidy.connected ){
|
||||
this.props.mopidyActions.getPlaylists();
|
||||
}
|
||||
if( this.props.spotify.authorized ){
|
||||
this.props.spotifyActions.getLibraryPlaylists();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps( nextProps ){
|
||||
if( !this.props.mopidy.connected && nextProps.mopidy.connected ) this.loadPlaylists();
|
||||
}
|
||||
|
||||
loadPlaylists(){
|
||||
this.props.spotifyActions.getLibraryPlaylists();
|
||||
this.props.mopidyActions.getPlaylists();
|
||||
if( !this.props.mopidy.connected && nextProps.mopidy.connected ){
|
||||
this.props.mopidyActions.getPlaylists();
|
||||
}
|
||||
if( !this.props.spotify.authorized && nextProps.spotify.authorized ){
|
||||
this.props.spotifyActions.getLibraryPlaylists();
|
||||
}
|
||||
}
|
||||
|
||||
compiledPlaylistSources(){
|
||||
|
||||
@ -51,7 +51,12 @@ aside{
|
||||
background: rgba( 0, 0, 0, 0.5 );
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&[disabled] {
|
||||
opacity: 0.3;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&:hover:not([disabled]) {
|
||||
background: rgba( 255, 255, 255, 0.1 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,4 +95,8 @@ main {
|
||||
|
||||
.one-liner{
|
||||
@include one_line_text;
|
||||
}
|
||||
|
||||
.grey-text {
|
||||
color: $mid_grey;
|
||||
}
|
||||
Reference in New Issue
Block a user