diff --git a/build_tools/auth_spotify.php b/build_tools/auth_spotify.php
index cb774118..205a1cdb 100755
--- a/build_tools/auth_spotify.php
+++ b/build_tools/auth_spotify.php
@@ -1,5 +1,4 @@
$_GET["error"],
+ "origin" => "auth_spotify"
+ );
- // Pass our error back to the popup opener
- ?>
-
-
+
+ {
return {
authorization_url: state.lastfm.authorization_url,
- authorized: state.lastfm.authorization,
+ authorized: state.lastfm.session,
authorizing: state.lastfm.authorizing
}
}
diff --git a/src/js/components/SpotifyAuthenticationFrame.js b/src/js/components/SpotifyAuthenticationFrame.js
index aefa4aa9..86a74d6a 100755
--- a/src/js/components/SpotifyAuthenticationFrame.js
+++ b/src/js/components/SpotifyAuthenticationFrame.js
@@ -21,20 +21,20 @@ class SpotifyAuthenticationFrame extends React.Component{
}
componentDidMount(){
-
let self = this;
- // Listen for incoming messages from the authorization iframe
- // This is triggered when the popup posts a message, which is then passed to
- // the iframe, and then passed on to the parent frame (our application)
+ // Listen for incoming messages from the authorization popup
window.addEventListener('message', function(event){
- self.handleMessage(event)
+ var data = JSON.parse(event.data);
+
+ // Only digest messages relevant to us
+ if (data.origin == 'auth_spotify'){
+ self.handleMessage(event, data);
+ }
}, false);
}
- handleMessage(event){
-
- var data = JSON.parse(event.data)
+ handleMessage(event, data){
// Only allow incoming data from our authorized authenticator proxy
var authorization_domain = this.props.authorization_url.substring(0,this.props.authorization_url.indexOf('/',8))
@@ -44,7 +44,7 @@ class SpotifyAuthenticationFrame extends React.Component{
}
// Spotify bounced with an error
- if (typeof(data.error) !== 'undefined'){
+ if (data.error !== undefined){
this.props.uiActions.createNotification(data.error,'bad')
// No errors? We're in!
@@ -80,7 +80,7 @@ class SpotifyAuthenticationFrame extends React.Component{
'playlist-read-collaborative',
'ugc-image-upload' // playlist image uploading
]
- var popup = window.open(url+'&scope='+scopes.join('%20'),"popup","height=500,width=350");
+ var popup = window.open(url+'&scope='+scopes.join('%20'),"popup","height=580,width=350");
// Start timer to check our popup's state
var timer = setInterval(checkPopup, 1000);
diff --git a/src/js/services/core/middleware.js b/src/js/services/core/middleware.js
index 63326fe8..3559a18f 100755
--- a/src/js/services/core/middleware.js
+++ b/src/js/services/core/middleware.js
@@ -97,6 +97,7 @@ const CoreMiddleware = (function(){
case 'CORE_START_SERVICES':
store.dispatch(mopidyActions.connect());
store.dispatch(pusherActions.connect());
+ store.dispatch(lastfmActions.connect());
next(action)
break
diff --git a/src/js/services/lastfm/actions.js b/src/js/services/lastfm/actions.js
index 162c2324..8c4c3805 100755
--- a/src/js/services/lastfm/actions.js
+++ b/src/js/services/lastfm/actions.js
@@ -59,8 +59,11 @@ export function set(data){
**/
export function authorizationGranted(data){
- data.token_expiry = new Date().getTime() + data.expires_in;
- return { type: 'LASTFM_AUTHORIZATION_GRANTED', data: data }
+ data.session.expiry = new Date().getTime() + 3600;
+ return {
+ type: 'LASTFM_AUTHORIZATION_GRANTED',
+ data: data
+ }
}
export function revokeAuthorization(){
@@ -70,12 +73,37 @@ export function revokeAuthorization(){
export function connect(){
return (dispatch, getState) => {
- dispatch({ type: 'LASTFM_CONNECTING' })
+ dispatch({ type: 'LASTFM_CONNECTING' });
- sendRequest(dispatch, getState, 'method=artist.getInfo&artist=')
+ // Authorized, dual-purpose our connection to get the current user
+ if (getState().lastfm.session){
+ dispatch(getMe());
+
+ // Not authorized, just use a generic lookup to test our connection
+ } else {
+ sendRequest(dispatch, getState, 'method=artist.getInfo&artist=')
+ .then(
+ response => {
+ dispatch({ type: 'LASTFM_CONNECTED' })
+ }
+ )
+ }
+ }
+}
+
+export function getMe(){
+ return (dispatch, getState) => {
+ var params = 'method=user.getInfo&user='+getState().lastfm.session.name
+ sendRequest(dispatch, getState, params)
.then(
response => {
- dispatch({ type: 'LASTFM_CONNECTED' })
+ if (response.user){
+ dispatch({
+ type: 'LASTFM_USER_LOADED',
+ user: response.user
+ });
+ dispatch({ type: 'LASTFM_CONNECTED' })
+ }
}
)
}
diff --git a/src/js/services/lastfm/middleware.js b/src/js/services/lastfm/middleware.js
new file mode 100755
index 00000000..6759089b
--- /dev/null
+++ b/src/js/services/lastfm/middleware.js
@@ -0,0 +1,43 @@
+
+import ReactGA from 'react-ga'
+
+var helpers = require('./../../helpers')
+var lastfmActions = require('./actions')
+var uiActions = require('../ui/actions')
+var pusherActions = require('../pusher/actions')
+
+const LastfmMiddleware = (function(){
+
+ /**
+ * The actual middleware inteceptor
+ **/
+ return store => next => action => {
+ var state = store.getState();
+
+ switch(action.type){
+
+ case 'LASTFM_USER_LOADED':
+ var user = Object.assign(
+ {},
+ action.user,
+ {
+ uri: "lastfm:user:"+action.user.name
+ }
+ );
+ store.dispatch({
+ type: "USER_LOADED",
+ key: user.uri,
+ user: user
+ });
+ next(action);
+ break;
+
+ // This action is irrelevant to us, pass it on to the next middleware
+ default:
+ return next(action);
+ }
+ }
+
+})();
+
+export default LastfmMiddleware
\ No newline at end of file
diff --git a/src/js/services/lastfm/reducer.js b/src/js/services/lastfm/reducer.js
index 93c2a228..d69fa469 100755
--- a/src/js/services/lastfm/reducer.js
+++ b/src/js/services/lastfm/reducer.js
@@ -13,22 +13,17 @@ export default function reducer(lastfm = {}, action){
return Object.assign({}, lastfm, action.data)
case 'LASTFM_AUTHORIZATION_GRANTED':
- return Object.assign({}, lastfm, {
- enabled: true,
+ return Object.assign({}, lastfm, {
authorizing: false,
- authorization: action.data,
- api_key: action.data.api_key,
- token_expiry: action.data.token_expiry
+ session: action.data.session
})
case 'LASTFM_AUTHORIZATION_REVOKED':
return Object.assign({}, lastfm, {
- authorizing: false,
- authorization: false,
- api_key: false,
- token_expiry: 0,
+ authorizing: false,
+ session: false,
me: false
- })
+ });
default:
return lastfm
diff --git a/src/js/services/localstorage/middleware.js b/src/js/services/localstorage/middleware.js
index f34b8db3..365d2b8a 100755
--- a/src/js/services/localstorage/middleware.js
+++ b/src/js/services/localstorage/middleware.js
@@ -167,6 +167,17 @@ const localstorageMiddleware = (function(){
);
localStorage.setItem('ui', JSON.stringify(ui))
break
+
+ case 'LASTFM_AUTHORIZATION_GRANTED':
+ var lastfm = JSON.parse(localStorage.getItem('lastfm') );
+ lastfm = Object.assign(
+ {},
+ {
+ session: action.data.session
+ }
+ );
+ localStorage.setItem('lastfm', JSON.stringify(lastfm));
+ break;
}
}
diff --git a/src/js/views/Settings.js b/src/js/views/Settings.js
index 1b4e7320..378b5567 100755
--- a/src/js/views/Settings.js
+++ b/src/js/views/Settings.js
@@ -15,11 +15,13 @@ import Header from '../components/Header'
import Parallax from '../components/Parallax'
import Icon from '../components/Icon'
import Thumbnail from '../components/Thumbnail'
+import URILink from '../components/URILink'
import * as coreActions from '../services/core/actions'
import * as uiActions from '../services/ui/actions'
import * as pusherActions from '../services/pusher/actions'
import * as mopidyActions from '../services/mopidy/actions'
+import * as lastfmActions from '../services/lastfm/actions'
import * as spotifyActions from '../services/spotify/actions'
class Settings extends React.Component {
@@ -109,21 +111,45 @@ class Settings extends React.Component {
if (user){
return (
-
+