From ba5bd5c91d0ea4cb21d391248e512a0fcffecbf9 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Sun, 11 Dec 2016 21:09:50 +1300 Subject: [PATCH] Send authorization via pusher (partial), need to fetch me on acceptance --- src/js/components/Modal/AddToPlaylistModal.js | 4 +- src/js/components/Modal/Modal.js | 4 ++ .../Modal/SendAuthorizationModal.js | 65 +++++++++++++++++++ .../components/SpotifyAuthenticationFrame.js | 4 +- src/js/components/Thumbnail.js | 18 ++--- src/js/services/localstorage/middleware.js | 3 +- src/js/services/pusher/actions.js | 4 +- src/js/services/pusher/middleware.js | 12 +++- src/js/views/Settings.js | 16 +++++ src/js/views/User.js | 4 ++ src/scss/components/_modal.scss | 14 ++-- 11 files changed, 126 insertions(+), 22 deletions(-) create mode 100755 src/js/components/Modal/SendAuthorizationModal.js diff --git a/src/js/components/Modal/AddToPlaylistModal.js b/src/js/components/Modal/AddToPlaylistModal.js index b1c8ec01..3b95e25e 100755 --- a/src/js/components/Modal/AddToPlaylistModal.js +++ b/src/js/components/Modal/AddToPlaylistModal.js @@ -25,11 +25,11 @@ export default class AddToPlaylistModal extends React.Component{ return (

Add to playlist

-
+
{ playlists.map( playlist => { return ( -
this.playlistSelected(playlist.uri) }> +
this.playlistSelected(playlist.uri) }>   { playlist.name } diff --git a/src/js/components/Modal/Modal.js b/src/js/components/Modal/Modal.js index 5f230379..2a743177 100755 --- a/src/js/components/Modal/Modal.js +++ b/src/js/components/Modal/Modal.js @@ -8,10 +8,12 @@ import Icon from '../Icon' import AddToPlaylistModal from './AddToPlaylistModal' import CreatePlaylistModal from './CreatePlaylistModal' import EditPlaylistModal from './EditPlaylistModal' +import SendAuthorizationModal from './SendAuthorizationModal' import * as uiActions from '../../services/ui/actions' import * as mopidyActions from '../../services/mopidy/actions' import * as spotifyActions from '../../services/spotify/actions' +import * as pusherActions from '../../services/pusher/actions' class Modal extends React.Component{ @@ -32,6 +34,7 @@ class Modal extends React.Component{ { this.props.modal.name == 'add_to_playlist' ? : null } { this.props.modal.name == 'create_playlist' ? : null } { this.props.modal.name == 'edit_playlist' ? : null } + { this.props.modal.name == 'send_authorization' ? : null }
@@ -52,6 +55,7 @@ const mapStateToProps = (state, ownProps) => { const mapDispatchToProps = (dispatch) => { return { uiActions: bindActionCreators(uiActions, dispatch), + pusherActions: bindActionCreators(pusherActions, dispatch), spotifyActions: bindActionCreators(spotifyActions, dispatch), mopidyActions: bindActionCreators(mopidyActions, dispatch) } diff --git a/src/js/components/Modal/SendAuthorizationModal.js b/src/js/components/Modal/SendAuthorizationModal.js new file mode 100755 index 00000000..237fcf34 --- /dev/null +++ b/src/js/components/Modal/SendAuthorizationModal.js @@ -0,0 +1,65 @@ + +import React, { PropTypes } from 'react' +import { connect } from 'react-redux' +import { Link } from 'react-router' +import { createStore, bindActionCreators } from 'redux' + +import * as uiActions from '../../services/ui/actions' +import * as helpers from '../../helpers' + +import Icon from '../Icon' + +class SendAuthorizationModal extends React.Component{ + + constructor(props){ + super(props) + } + + handleClick(e, connectionid){ + e.preventDefault() + var data = { + recipients: [connectionid], + action: 'send_authorization', + data: this.props.authorization + } + this.props.pusherActions.instruct( 'broadcast', data ) + this.props.uiActions.closeModal() + return false; + } + + render(){ + return ( +
+

Share Spotify authentication

+
+ { + this.props.connections.map( (connection, index) => { + return ( +
this.handleClick(e, connection.connectionid) }> + { connection.username } +   + ({ connection.ip }) +
+ ); + }) + } +
+
+ ) + } +} + +const mapStateToProps = (state, ownProps) => { + return { + authorization: state.spotify.authorization, + connections: state.pusher.connections + } +} + +const mapDispatchToProps = (dispatch) => { + return { + uiActions: bindActionCreators(uiActions, dispatch) + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(SendAuthorizationModal) \ No newline at end of file diff --git a/src/js/components/SpotifyAuthenticationFrame.js b/src/js/components/SpotifyAuthenticationFrame.js index d70369bf..e6216c44 100755 --- a/src/js/components/SpotifyAuthenticationFrame.js +++ b/src/js/components/SpotifyAuthenticationFrame.js @@ -99,12 +99,12 @@ class SpotifyAuthenticationFrame extends React.Component{ render(){ return ( -
+ { this.renderAuthorizeButton() }    { this.renderRefreshButton() } -
+ ); } } diff --git a/src/js/components/Thumbnail.js b/src/js/components/Thumbnail.js index fc9e6c2f..0a1ce0bf 100755 --- a/src/js/components/Thumbnail.js +++ b/src/js/components/Thumbnail.js @@ -13,21 +13,21 @@ export default class Thumbnail extends React.Component{ shouldComponentUpdate(nextProps, nextState){ // no images at all, and we already know it - if( !this.props.image && - !this.props.images && - !nextProps.image && - !nextProps.images ){ - return false - } + if( + typeof(nextProps.image) == 'undefined' && + typeof(this.props.image) == 'undefined' && + typeof(nextProps.images) == 'undefined' && + typeof(this.props.images) == 'undefined' + ) return false // image changed - if( this.props.image && !nextProps.image ) return true if( !this.props.image && nextProps.image ) return true + if( this.props.image && nextProps.image ) return true if( this.props.image != nextProps.image ) return true // images array changed - if( this.props.images && !nextProps.images ) return true - if( !this.props.images && nextProps.images ) return true + if( typeof(this.props.images) === 'undefined' && nextProps.images ) return true + if( this.props.images && typeof(nextProps.images) === 'undefined' ) return true if( this.props.images.length != nextProps.images.length ) return true // image item changed diff --git a/src/js/services/localstorage/middleware.js b/src/js/services/localstorage/middleware.js index 01b275c3..f0299aa7 100755 --- a/src/js/services/localstorage/middleware.js +++ b/src/js/services/localstorage/middleware.js @@ -12,7 +12,7 @@ const localstorageMiddleware = (function(){ // append our state to a global variable. This gives us access to debug the store at any point window._store = store - //console.log(action) + console.log(action) switch( action.type ){ @@ -70,6 +70,7 @@ const localstorageMiddleware = (function(){ Object.assign( spotify,{ authorized: true, + authorization: action.data, access_token: action.data.access_token, refresh_token: action.data.refresh_token, token_expiry: action.data.token_expiry diff --git a/src/js/services/pusher/actions.js b/src/js/services/pusher/actions.js index 7e5f00a7..585d79c6 100755 --- a/src/js/services/pusher/actions.js +++ b/src/js/services/pusher/actions.js @@ -43,10 +43,10 @@ export function getConnectionList(){ } } -export function instruct( action, data = null ){ +export function instruct( message_type, data = null ){ return { type: 'PUSHER_INSTRUCT', - action: action, + message_type: message_type, data: data } } diff --git a/src/js/services/pusher/middleware.js b/src/js/services/pusher/middleware.js index 525aa47c..977dd06f 100755 --- a/src/js/services/pusher/middleware.js +++ b/src/js/services/pusher/middleware.js @@ -9,6 +9,7 @@ const PusherMiddleware = (function(){ // handle all manner of socket messages const handleMessage = (ws, store, message) => { + console.log(message) switch( message.action ){ default: var name = 'unspecified' @@ -87,7 +88,7 @@ const PusherMiddleware = (function(){ break; case 'PUSHER_INSTRUCT': - switch( action.action ){ + switch( action.message_type ){ case 'query': makeRequest( action.data ) break @@ -150,6 +151,15 @@ const PusherMiddleware = (function(){ var notification = new notification( title, options ); break; + case 'PUSHER_SEND_AUTHORIZATION': + if( window.confirm('Spotify authorization received. Do you want to import?') ){ + store.dispatch({ type: 'SPOTIFY_AUTHORIZATION_GRANTED', data: action.data }) + window.location.reload(true) + }else{ + console.log('Authorization ignored') + } + break + // This action is irrelevant to us, pass it on to the next middleware default: return next(action); diff --git a/src/js/views/Settings.js b/src/js/views/Settings.js index 941fd972..771545f6 100755 --- a/src/js/views/Settings.js +++ b/src/js/views/Settings.js @@ -13,6 +13,7 @@ import VersionManager from '../components/VersionManager' import Header from '../components/Header' import Thumbnail from '../components/Thumbnail' +import * as uiActions from '../services/ui/actions' import * as pusherActions from '../services/pusher/actions' import * as mopidyActions from '../services/mopidy/actions' import * as spotifyActions from '../services/spotify/actions' @@ -108,6 +109,18 @@ class Settings extends React.Component{ } } + renderSendAuthorizationButton(){ + if( !this.props.spotify.authorized ) return null + + return ( + + ) + } + render(){ return (
@@ -214,6 +227,8 @@ class Settings extends React.Component{
Authentication
+   + { this.renderSendAuthorizationButton() }
@@ -278,6 +293,7 @@ const mapStateToProps = (state, ownProps) => { const mapDispatchToProps = (dispatch) => { return { + uiActions: bindActionCreators(uiActions, dispatch), pusherActions: bindActionCreators(pusherActions, dispatch), mopidyActions: bindActionCreators(mopidyActions, dispatch), spotifyActions: bindActionCreators(spotifyActions, dispatch) diff --git a/src/js/views/User.js b/src/js/views/User.js index 502a6121..305ce8a5 100755 --- a/src/js/views/User.js +++ b/src/js/views/User.js @@ -8,6 +8,7 @@ import Thumbnail from '../components/Thumbnail' import PlaylistGrid from '../components/PlaylistGrid' import FollowButton from '../components/FollowButton' import LazyLoadListener from '../components/LazyLoadListener' +import Header from '../components/Header' import * as helpers from '../helpers' import * as mopidyActions from '../services/mopidy/actions' @@ -51,6 +52,9 @@ class User extends React.Component{ return (
+ +
+
diff --git a/src/scss/components/_modal.scss b/src/scss/components/_modal.scss index c1d9af76..79656d22 100755 --- a/src/scss/components/_modal.scss +++ b/src/scss/components/_modal.scss @@ -66,18 +66,22 @@ } } - .playlists { + .list { @include clearfix(); - .playlist { + .list-item { float: left; box-sizing: border-box; display: block; width: 49%; - padding: 16px 20px 16px 30px; + padding: 16px 18px; border-bottom: 1px solid $mid_grey; position: relative; + &.playlist { + padding-left: 30px; + } + .source { position: absolute; top: 18px; @@ -108,8 +112,8 @@ padding: 50px; width: 80%; - .playlists { - .playlist { + .list { + .list-item { float: none !important; width: auto; }