Files
Iris/src/js/services/pusher/middleware.js

200 lines
7.3 KiB
JavaScript
Raw Normal View History

2016-10-27 16:58:11 +13:00
var pusherActions = require('./actions.js')
var uiActions = require('../ui/actions.js')
2016-10-27 21:20:05 +13:00
var helpers = require('../../helpers.js')
2016-10-27 16:58:11 +13:00
const PusherMiddleware = (function(){
// container for the actual Mopidy socket
var socket = null;
// handle all manner of socket messages
const handleMessage = (ws, store, message) => {
switch( message.action ){
default:
2016-11-21 07:59:52 +13:00
var name = 'unspecified'
if( message.action ) name = message.action
name = name.replace('get_','').toUpperCase()
2016-10-27 21:20:05 +13:00
store.dispatch({ type: 'PUSHER_'+name, data: message.data })
2016-10-27 16:58:11 +13:00
}
}
2016-10-27 21:20:05 +13:00
const makeRequest = (data) => {
data.type = 'query';
data.message_id = helpers.generateGuid();
socket.send( JSON.stringify(data) );
}
const broadcast = (data) => {
data.type = 'broadcast';
socket.send( JSON.stringify(data) );
}
2016-10-27 16:58:11 +13:00
/**
* Middleware
*
* This behaves like an action interceptor. We listen for specific actions
* and handle special functionality. If the action is not in our switch, then
* it just proceeds to the next middleware, or default functionality
**/
return store => next => action => {
switch(action.type) {
case 'PUSHER_CONNECT':
if(socket != null) socket.close();
store.dispatch({ type: 'PUSHER_CONNECTING' });
var state = store.getState();
var connection = {
clientid: Math.random().toString(36).substr(2, 9),
connectionid: helpers.generateGuid(),
username: Math.random().toString(36).substr(2, 9)
}
2016-10-28 15:58:07 +13:00
if( state.pusher.username ) connection.username = state.pusher.username;
2016-10-27 16:58:11 +13:00
socket = new WebSocket(
'ws://'+state.mopidy.host+':'+state.pusher.port+'/pusher',
[ connection.clientid, connection.connectionid, connection.username ]
2016-10-27 16:58:11 +13:00
);
socket.onopen = () => {
store.dispatch({ type: 'PUSHER_CONNECTED', connection: connection });
2016-10-28 15:58:07 +13:00
store.dispatch({ type: 'PUSHER_SET_USERNAME', username: connection.username });
2016-12-20 16:58:20 +13:00
makeRequest({ action: 'get_radio' });
2016-10-27 16:58:11 +13:00
};
socket.onmessage = (message) => {
2016-10-27 16:58:11 +13:00
var message = JSON.parse(message.data);
handleMessage( socket, store, message )
};
break;
2016-10-27 21:20:05 +13:00
case 'PUSHER_CONNECTED':
makeRequest({ action: 'get_version' });
return next(action);
break;
case 'PUSHER_UPGRADING':
makeRequest({ action: 'perform_upgrade' });
return next(action);
break;
2016-10-28 10:48:55 +13:00
case 'PUSHER_CLIENT_CONNECTED':
makeRequest({ action: 'get_connections' });
return next(action);
break;
case 'PUSHER_INSTRUCT':
switch( action.message_type ){
case 'query':
makeRequest( action.data )
break
case 'broadcast':
broadcast( action.data )
break
}
break;
case 'PUSHER_DEBUG':
switch( action.call ){
case 'query':
makeRequest( action.data )
// THIS DOES NOT RETURN A PROMISE SO CAN'T DETECT RELATED RESPONSES
/*.then( response => {
store.dispatch({ type: 'DEBUG', response: response })
})*/
break
case 'broadcast':
broadcast( action.data )
/*.then( response => {
store.dispatch({ type: 'DEBUG', response: response })
})*/
break
default:
store.dispatch({ type: 'DEBUG', response: '{ "error": "Invalid call" }' })
break
}
2016-10-27 21:20:05 +13:00
break;
case 'PUSHER_SEND_BROADCAST':
broadcast({ action: action.action, data: action.data });
break;
case 'PUSHER_NOTIFICATION':
case 'PUSHER_BROADCAST':
var notification = window.Notification || window.mozNotification || window.webkitNotification;
if ('undefined' === typeof notification) return false;
if ('undefined' !== typeof notification) notification.requestPermission(function(permission){});
// handle nested data objects
var data = {}
if( typeof(action.data) ) data = action.data
if( typeof(data.data) ) data = Object.assign({}, data, data.data)
// construct our browser notification
var title = '';
var options = {
body: '',
dir: 'auto',
lang: 'EN',
tag: 'iris'
};
if( data.title ) title = data.title;
if( data.body ) options.body = data.body;
if( data.icon ) options.icon = data.icon;
// make it so
var notification = new notification( title, options );
2016-12-20 16:58:20 +13:00
break
case 'PUSHER_SEND_AUTHORIZATION':
if( window.confirm('Spotify authorization for user '+action.data.me.id+' received. Do you want to import?') ){
// remove any existing authentication
store.dispatch({ type: 'SPOTIFY_AUTHORIZATION_REVOKED' })
// import our new authentication
store.dispatch({ type: 'SPOTIFY_ME_LOADED', data: action.data.me })
store.dispatch({ type: 'SPOTIFY_AUTHORIZATION_GRANTED', data: action.data.authorization })
}else{
console.log('Authorization ignored')
}
break
2016-12-20 16:58:20 +13:00
case 'PUSHER_START_RADIO':
var data = {
action: 'start_radio',
seed_artists: [],
seed_genres: [],
seed_tracks: []
}
for( var i = 0; i < action.uris.length; i++){
switch( helpers.uriType( action.uris[i] ) ){
case 'artist':
data.seed_artists.push( action.uris[i] );
break;
case 'track':
data.seed_tracks.push( action.uris[i] );
break;
}
}
makeRequest( data )
break
2016-10-27 16:58:11 +13:00
// This action is irrelevant to us, pass it on to the next middleware
default:
return next(action);
}
}
})();
export default PusherMiddleware