2018-09-24 08:26:50 +12:00
|
|
|
|
|
|
|
|
import ReactGA from 'react-ga'
|
|
|
|
|
|
2018-09-24 13:21:08 +12:00
|
|
|
var helpers = require('../../helpers');
|
|
|
|
|
var coreActions = require('../core/actions');
|
|
|
|
|
var uiActions = require('../ui/actions');
|
|
|
|
|
var pusherActions = require('../pusher/actions');
|
|
|
|
|
var snapcastActions = require('./actions');
|
2018-09-24 08:26:50 +12:00
|
|
|
|
|
|
|
|
const SnapcastMiddleware = (function(){
|
|
|
|
|
|
2018-09-24 13:21:08 +12:00
|
|
|
// A snapcast request is an alias of the Pusher request
|
|
|
|
|
const request = (store, params = null, response_callback = null, error_callback = null) => {
|
|
|
|
|
store.dispatch(
|
2018-09-24 16:10:42 +12:00
|
|
|
pusherActions.request(
|
2018-09-24 13:21:08 +12:00
|
|
|
'snapcast_instruct',
|
|
|
|
|
params,
|
|
|
|
|
response_callback,
|
|
|
|
|
error_callback
|
|
|
|
|
)
|
|
|
|
|
);
|
2018-09-24 08:26:50 +12:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return store => next => action => {
|
2018-09-27 20:43:42 +12:00
|
|
|
var snapcast = store.getState().snapcast;
|
|
|
|
|
|
2018-09-24 08:26:50 +12:00
|
|
|
switch(action.type){
|
|
|
|
|
|
|
|
|
|
case 'SNAPCAST_GET_SERVER':
|
2018-09-24 13:21:08 +12:00
|
|
|
request(
|
|
|
|
|
store,
|
|
|
|
|
{
|
|
|
|
|
method: 'Server.GetStatus'
|
|
|
|
|
},
|
|
|
|
|
response => {
|
2018-09-27 20:43:42 +12:00
|
|
|
console.log(response);
|
|
|
|
|
store.dispatch(snapcastActions.serverLoaded(response.server));
|
2018-09-24 13:21:08 +12:00
|
|
|
},
|
|
|
|
|
error => {
|
|
|
|
|
store.dispatch(coreActions.handleException(
|
|
|
|
|
'Could not get server',
|
|
|
|
|
error
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
);
|
2018-09-24 08:26:50 +12:00
|
|
|
break
|
|
|
|
|
|
|
|
|
|
case 'SNAPCAST_SERVER_LOADED':
|
2018-09-28 21:29:09 +12:00
|
|
|
store.dispatch(snapcastActions.groupsLoaded(action.server.groups, true));
|
|
|
|
|
store.dispatch(snapcastActions.streamsLoaded(action.server.streams, true));
|
2018-09-27 20:43:42 +12:00
|
|
|
|
|
|
|
|
// Snapcast double-nests the server object
|
|
|
|
|
action.server = action.server.server;
|
|
|
|
|
|
|
|
|
|
next(action);
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case 'SNAPCAST_GROUPS_LOADED':
|
|
|
|
|
var groups_index = Object.assign({}, snapcast.groups);
|
|
|
|
|
var groups_loaded = [];
|
|
|
|
|
var clients_loaded = [];
|
|
|
|
|
|
|
|
|
|
for (var raw_group of action.groups){
|
|
|
|
|
var group = helpers.formatGroup(raw_group);
|
|
|
|
|
|
|
|
|
|
if (groups_index[group.id]){
|
|
|
|
|
group = Object.assign({}, groups_index[group.id], group);
|
2018-09-24 08:26:50 +12:00
|
|
|
}
|
|
|
|
|
|
2018-09-27 20:43:42 +12:00
|
|
|
if (raw_group.clients){
|
|
|
|
|
group.clients_ids = helpers.arrayOf('id', raw_group.clients);
|
|
|
|
|
clients_loaded = [...clients_loaded, ...raw_group.clients];
|
2018-09-24 08:26:50 +12:00
|
|
|
}
|
|
|
|
|
|
2018-09-27 20:43:42 +12:00
|
|
|
groups_loaded.push(group);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
action.groups = groups_loaded;
|
|
|
|
|
|
|
|
|
|
if (clients_loaded.length > 0){
|
|
|
|
|
store.dispatch(snapcastActions.clientsLoaded(clients_loaded));
|
2018-09-24 08:26:50 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
next(action);
|
|
|
|
|
break
|
|
|
|
|
|
2018-09-27 20:43:42 +12:00
|
|
|
case 'SNAPCAST_CLIENTS_LOADED':
|
|
|
|
|
var clients_index = Object.assign({}, snapcast.clients);
|
|
|
|
|
var clients_loaded = [];
|
|
|
|
|
|
|
|
|
|
for (var raw_client of action.clients){
|
|
|
|
|
var client = helpers.formatClient(raw_client);
|
|
|
|
|
|
|
|
|
|
if (clients_index[client.id]){
|
|
|
|
|
client = Object.assign({}, clients_index[client.id], client);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clients_loaded.push(client);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
action.clients = clients_loaded;
|
|
|
|
|
|
|
|
|
|
next(action);
|
|
|
|
|
break;
|
|
|
|
|
|
2018-09-24 08:26:50 +12:00
|
|
|
case 'SNAPCAST_SET_CLIENT_NAME':
|
2018-09-27 20:43:42 +12:00
|
|
|
var client = snapcast.clients[action.id];
|
2018-09-24 08:26:50 +12:00
|
|
|
var data = {
|
|
|
|
|
method: 'Client.SetName',
|
|
|
|
|
params: {
|
|
|
|
|
id: action.id,
|
|
|
|
|
name: action.name
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-24 13:21:08 +12:00
|
|
|
request(
|
|
|
|
|
store,
|
|
|
|
|
data,
|
|
|
|
|
response => {
|
2018-09-27 20:43:42 +12:00
|
|
|
store.dispatch(snapcastActions.clientLoaded(
|
|
|
|
|
{
|
|
|
|
|
id: action.id,
|
|
|
|
|
name: response.name
|
2018-09-24 13:21:08 +12:00
|
|
|
}
|
2018-09-27 20:43:42 +12:00
|
|
|
));
|
2018-09-24 13:21:08 +12:00
|
|
|
}
|
|
|
|
|
);
|
2018-09-24 08:26:50 +12:00
|
|
|
break
|
|
|
|
|
|
|
|
|
|
case 'SNAPCAST_SET_CLIENT_MUTE':
|
|
|
|
|
var client = store.getState().snapcast.clients[action.id];
|
|
|
|
|
var data = {
|
|
|
|
|
method: 'Client.SetVolume',
|
|
|
|
|
params: {
|
|
|
|
|
id: action.id,
|
|
|
|
|
volume: {
|
|
|
|
|
muted: action.mute,
|
2018-09-27 20:43:42 +12:00
|
|
|
percent: client.volume,
|
2018-09-24 08:26:50 +12:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-24 13:21:08 +12:00
|
|
|
request(
|
|
|
|
|
store,
|
|
|
|
|
data,
|
|
|
|
|
response => {
|
2018-09-27 20:43:42 +12:00
|
|
|
store.dispatch(snapcastActions.clientLoaded(
|
|
|
|
|
{
|
|
|
|
|
id: action.id,
|
|
|
|
|
volume: response.volume.percent,
|
|
|
|
|
mute: response.volume.muted
|
2018-09-24 13:21:08 +12:00
|
|
|
}
|
2018-09-27 20:43:42 +12:00
|
|
|
));
|
2018-09-24 13:21:08 +12:00
|
|
|
},
|
|
|
|
|
error => {
|
|
|
|
|
store.dispatch(coreActions.handleException(
|
|
|
|
|
'Error',
|
|
|
|
|
error,
|
|
|
|
|
error.message
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
);
|
2018-09-24 08:26:50 +12:00
|
|
|
break
|
|
|
|
|
|
|
|
|
|
case 'SNAPCAST_SET_CLIENT_VOLUME':
|
2018-09-27 20:43:42 +12:00
|
|
|
var client = snapcast.clients[action.id];
|
|
|
|
|
|
2018-09-24 08:26:50 +12:00
|
|
|
var data = {
|
|
|
|
|
method: 'Client.SetVolume',
|
|
|
|
|
params: {
|
|
|
|
|
id: action.id,
|
|
|
|
|
volume: {
|
2018-09-27 20:43:42 +12:00
|
|
|
muted: client.mute,
|
|
|
|
|
percent: action.volume
|
2018-09-24 08:26:50 +12:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-24 13:21:08 +12:00
|
|
|
request(
|
|
|
|
|
store,
|
|
|
|
|
data,
|
|
|
|
|
response => {
|
2018-09-27 20:43:42 +12:00
|
|
|
store.dispatch(snapcastActions.clientLoaded(
|
|
|
|
|
{
|
|
|
|
|
id: action.id,
|
|
|
|
|
volume: response.volume.percent
|
2018-09-24 13:21:08 +12:00
|
|
|
}
|
2018-09-27 20:43:42 +12:00
|
|
|
));
|
2018-09-24 13:21:08 +12:00
|
|
|
},
|
|
|
|
|
error => {
|
|
|
|
|
store.dispatch(coreActions.handleException(
|
|
|
|
|
'Error',
|
|
|
|
|
error,
|
|
|
|
|
error.message
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
);
|
2018-09-24 08:26:50 +12:00
|
|
|
break
|
|
|
|
|
|
|
|
|
|
case 'SNAPCAST_SET_CLIENT_LATENCY':
|
|
|
|
|
var client = store.getState().snapcast.clients[action.id];
|
|
|
|
|
var data = {
|
|
|
|
|
method: 'Client.SetLatency',
|
|
|
|
|
params: {
|
|
|
|
|
id: action.id,
|
|
|
|
|
latency: action.latency
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-24 13:21:08 +12:00
|
|
|
request(
|
2018-09-27 20:43:42 +12:00
|
|
|
store,
|
|
|
|
|
data,
|
2018-09-24 13:21:08 +12:00
|
|
|
response => {
|
2018-09-27 20:43:42 +12:00
|
|
|
store.dispatch(snapcastActions.clientLoaded(
|
|
|
|
|
{
|
|
|
|
|
id: action.id,
|
|
|
|
|
latency: response.latency
|
2018-09-24 13:21:08 +12:00
|
|
|
}
|
2018-09-27 20:43:42 +12:00
|
|
|
));
|
2018-09-24 13:21:08 +12:00
|
|
|
},
|
|
|
|
|
error => {
|
|
|
|
|
store.dispatch(coreActions.handleException(
|
|
|
|
|
'Error',
|
|
|
|
|
error,
|
|
|
|
|
error.message
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
);
|
2018-09-24 08:26:50 +12:00
|
|
|
break
|
|
|
|
|
|
2018-09-27 20:43:42 +12:00
|
|
|
case 'SNAPCAST_SET_CLIENT_COMMAND':
|
2018-09-28 16:02:53 +12:00
|
|
|
var client_commands_index = Object.assign({}, snapcast.client_commands);
|
|
|
|
|
|
|
|
|
|
if (client_commands_index[action.id]){
|
|
|
|
|
var client_command = Object.assign({}, client_commands_index[action.id], action.command);
|
|
|
|
|
} else {
|
|
|
|
|
var client_command = action.command;
|
|
|
|
|
}
|
|
|
|
|
client_commands_index[action.id] = client_command;
|
|
|
|
|
|
|
|
|
|
store.dispatch(snapcastActions.clientCommandsUpdated(client_commands_index));
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
case 'SNAPCAST_SEND_CLIENT_COMMAND':
|
2018-09-28 21:29:09 +12:00
|
|
|
|
|
|
|
|
// Prepare our command
|
|
|
|
|
// We try and make it cross-origin compatible
|
|
|
|
|
var command = JSON.parse(action.command);
|
|
|
|
|
command.crossDomain = true;
|
|
|
|
|
|
|
|
|
|
$.ajax(command)
|
|
|
|
|
.then(
|
|
|
|
|
response => {
|
|
|
|
|
console.log(response);
|
|
|
|
|
},
|
|
|
|
|
(xhr, status, error) => {
|
|
|
|
|
console.error(error);
|
|
|
|
|
}
|
|
|
|
|
);
|
2018-09-27 20:43:42 +12:00
|
|
|
break
|
|
|
|
|
|
2018-09-24 08:26:50 +12:00
|
|
|
case 'SNAPCAST_SET_CLIENT_GROUP':
|
|
|
|
|
|
2018-09-27 20:43:42 +12:00
|
|
|
var group = snapcast.groups[action.group_id];
|
2018-09-24 08:26:50 +12:00
|
|
|
var clients_ids = group.clients_ids;
|
|
|
|
|
var clients_ids_index = clients_ids.indexOf(action.id);
|
|
|
|
|
|
|
|
|
|
// Not in group (yet), so add it
|
|
|
|
|
if (clients_ids_index <= -1){
|
|
|
|
|
clients_ids.push(action.id);
|
|
|
|
|
|
|
|
|
|
// Already there, so remove it
|
|
|
|
|
} else {
|
|
|
|
|
clients_ids.splice(clients_ids_index, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var data = {
|
|
|
|
|
method: 'Group.SetClients',
|
|
|
|
|
params: {
|
|
|
|
|
id: action.group_id,
|
|
|
|
|
clients: clients_ids
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-24 13:21:08 +12:00
|
|
|
request(
|
|
|
|
|
store,
|
|
|
|
|
data,
|
|
|
|
|
response => {
|
|
|
|
|
store.dispatch(snapcastActions.serverLoaded(response.server));
|
|
|
|
|
},
|
|
|
|
|
error => {
|
|
|
|
|
store.dispatch(coreActions.handleException(
|
|
|
|
|
'Error',
|
|
|
|
|
error,
|
|
|
|
|
error.message
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
);
|
2018-09-24 08:26:50 +12:00
|
|
|
break
|
|
|
|
|
|
|
|
|
|
case 'SNAPCAST_DELETE_CLIENT':
|
|
|
|
|
var data = {
|
|
|
|
|
method: 'Server.DeleteClient',
|
|
|
|
|
params: {
|
|
|
|
|
id: action.id
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-24 13:21:08 +12:00
|
|
|
request(
|
|
|
|
|
store,
|
|
|
|
|
data,
|
|
|
|
|
response => {
|
|
|
|
|
store.dispatch({
|
|
|
|
|
type: 'SNAPCAST_CLIENT_REMOVED',
|
|
|
|
|
key: action.data.params.id
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
error => {
|
|
|
|
|
store.dispatch(coreActions.handleException(
|
|
|
|
|
'Error',
|
|
|
|
|
error,
|
|
|
|
|
error.message
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
);
|
2018-09-24 08:26:50 +12:00
|
|
|
break
|
|
|
|
|
|
|
|
|
|
case 'SNAPCAST_SET_GROUP_STREAM':
|
|
|
|
|
var group = store.getState().snapcast.groups[action.id];
|
|
|
|
|
var data = {
|
|
|
|
|
method: 'Group.SetStream',
|
|
|
|
|
params: {
|
|
|
|
|
id: action.id,
|
|
|
|
|
stream_id: action.stream_id
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-24 13:21:08 +12:00
|
|
|
request(
|
|
|
|
|
store,
|
|
|
|
|
data,
|
|
|
|
|
response => {
|
2018-09-27 20:43:42 +12:00
|
|
|
store.dispatch(snapcastActions.groupLoaded(
|
|
|
|
|
{
|
|
|
|
|
id: action.id,
|
2018-09-24 13:21:08 +12:00
|
|
|
stream_id: action.stream_id
|
|
|
|
|
}
|
2018-09-27 20:43:42 +12:00
|
|
|
));
|
2018-09-24 13:21:08 +12:00
|
|
|
},
|
|
|
|
|
error => {
|
|
|
|
|
store.dispatch(coreActions.handleException(
|
|
|
|
|
'Could not change stream',
|
|
|
|
|
error,
|
|
|
|
|
error.message
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
);
|
2018-09-24 08:26:50 +12:00
|
|
|
break
|
|
|
|
|
|
|
|
|
|
case 'SNAPCAST_SET_GROUP_MUTE':
|
|
|
|
|
var group = store.getState().snapcast.groups[action.id];
|
|
|
|
|
var data = {
|
|
|
|
|
method: 'Group.SetMute',
|
|
|
|
|
params: {
|
|
|
|
|
id: action.id,
|
|
|
|
|
mute: action.mute
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-24 13:21:08 +12:00
|
|
|
request(
|
|
|
|
|
store,
|
|
|
|
|
data,
|
|
|
|
|
response => {
|
2018-09-27 20:43:42 +12:00
|
|
|
store.dispatch(snapcastActions.groupLoaded(
|
|
|
|
|
{
|
|
|
|
|
id: action.id,
|
2018-09-24 13:21:08 +12:00
|
|
|
muted: response.mute
|
|
|
|
|
}
|
2018-09-27 20:43:42 +12:00
|
|
|
));
|
2018-09-24 13:21:08 +12:00
|
|
|
},
|
|
|
|
|
error => {
|
|
|
|
|
store.dispatch(coreActions.handleException(
|
|
|
|
|
'Could not toggle mute',
|
|
|
|
|
error,
|
|
|
|
|
error.message
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
);
|
2018-09-24 08:26:50 +12:00
|
|
|
break
|
|
|
|
|
|
|
|
|
|
case 'SNAPCAST_SET_GROUP_VOLUME':
|
|
|
|
|
var clients_to_update = [];
|
2018-09-27 20:43:42 +12:00
|
|
|
var group = snapcast.groups[action.id];
|
2018-09-24 08:26:50 +12:00
|
|
|
var change = action.percent - action.old_percent;
|
|
|
|
|
|
2018-09-27 20:43:42 +12:00
|
|
|
for (var client_id of group.clients_ids){
|
2018-09-24 08:26:50 +12:00
|
|
|
|
|
|
|
|
// Apply the change proportionately to each client
|
2018-09-27 20:43:42 +12:00
|
|
|
var client = snapcast.clients[client_id];
|
|
|
|
|
var current_volume = client.volume;
|
|
|
|
|
var new_volume = current_volume + change;
|
2018-09-24 08:26:50 +12:00
|
|
|
|
|
|
|
|
// Only change if the client is within min/max limits
|
2018-09-27 20:43:42 +12:00
|
|
|
if ((change > 0 && current_volume < 100) || (change < 0 && current_volume > 0)){
|
2018-09-24 08:26:50 +12:00
|
|
|
clients_to_update.push({
|
|
|
|
|
id: client.id,
|
2018-09-27 20:43:42 +12:00
|
|
|
volume: new_volume
|
2018-09-24 08:26:50 +12:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Loop our required changes, and post each to Snapcast
|
2018-09-27 20:43:42 +12:00
|
|
|
for (var client_to_update of clients_to_update){
|
|
|
|
|
var volume = client_to_update.volume + ((group.clients_ids.length - clients_to_update.length) * change);
|
2018-09-24 08:26:50 +12:00
|
|
|
|
|
|
|
|
// Make sure we're not creating an impossible percent
|
2018-09-27 20:43:42 +12:00
|
|
|
if (volume < 0){
|
|
|
|
|
volume = 0;
|
|
|
|
|
} else if (volume > 100){
|
|
|
|
|
volume = 100;
|
2018-09-24 08:26:50 +12:00
|
|
|
}
|
|
|
|
|
|
2018-09-27 20:43:42 +12:00
|
|
|
store.dispatch(snapcastActions.setClientVolume(client_to_update.id, volume));
|
2018-09-24 08:26:50 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This action is irrelevant to us, pass it on to the next middleware
|
|
|
|
|
default:
|
|
|
|
|
return next(action);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
|
export default SnapcastMiddleware
|