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

469 lines
13 KiB
JavaScript
Raw Normal View History

2018-09-24 08:26:50 +12:00
2019-09-05 15:36:11 +12:00
import ReactGA from 'react-ga';
const helpers = require('../../helpers');
const coreActions = require('../core/actions');
const uiActions = require('../ui/actions');
const pusherActions = require('../pusher/actions');
const snapcastActions = require('./actions');
const SnapcastMiddleware = (function () {
// 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-11-03 23:19:03 +13:00
'snapcast',
params,
response_callback,
2019-09-05 15:36:11 +12:00
error_callback,
),
);
};
return (store) => (next) => (action) => {
const { snapcast } = store.getState();
switch (action.type) {
case 'SNAPCAST_GET_SERVER':
request(
store,
{
2019-09-05 15:36:11 +12:00
method: 'Server.GetStatus',
},
2019-09-05 15:36:11 +12:00
(response) => {
store.dispatch(snapcastActions.serverLoaded(response.server));
},
(error) => {
store.dispatch(coreActions.handleException(
'Could not get server',
error,
));
},
);
2019-09-05 15:36:11 +12:00
break;
case 'SNAPCAST_SERVER_LOADED':
store.dispatch(snapcastActions.groupsLoaded(action.server.groups, true));
store.dispatch(snapcastActions.streamsLoaded(action.server.streams, true));
// Snapcast double-nests the server object
action.server = action.server.server;
next(action);
break;
case 'SNAPCAST_GROUPS_LOADED':
var groups_index = { ...snapcast.groups };
var groups_loaded = [];
var clients_loaded = [];
for (const raw_group of action.groups) {
var group = helpers.formatGroup(raw_group);
if (groups_index[group.id]) {
group = { ...groups_index[group.id], ...group };
}
if (raw_group.clients) {
group.clients_ids = helpers.arrayOf('id', raw_group.clients);
clients_loaded = [...clients_loaded, ...raw_group.clients];
}
groups_loaded.push(group);
}
action.groups = groups_loaded;
if (clients_loaded.length > 0) {
store.dispatch(snapcastActions.clientsLoaded(clients_loaded, action.flush));
}
next(action);
break;
case 'SNAPCAST_CLIENTS_LOADED':
var clients_index = { ...snapcast.clients };
var clients_loaded = [];
for (const raw_client of action.clients) {
var client = helpers.formatClient(raw_client);
if (clients_index[client.id]) {
client = { ...clients_index[client.id], ...client };
}
clients_loaded.push(client);
}
action.clients = clients_loaded;
next(action);
break;
case 'SNAPCAST_SET_CLIENT_NAME':
var client = snapcast.clients[action.id];
var data = {
method: 'Client.SetName',
params: {
id: action.id,
name: action.name,
},
};
request(
store,
data,
(response) => {
store.dispatch(snapcastActions.clientLoaded(
{
id: action.id,
name: response.name,
},
));
},
);
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,
percent: client.volume,
},
},
};
request(
store,
data,
2019-09-05 15:36:11 +12:00
(response) => {
store.dispatch(snapcastActions.clientLoaded(
{
id: action.id,
volume: response.volume.percent,
mute: response.volume.muted,
},
));
},
(error) => {
store.dispatch(coreActions.handleException(
'Error',
error,
error.message,
));
},
);
break;
case 'SNAPCAST_SET_CLIENT_VOLUME':
var client = snapcast.clients[action.id];
var data = {
method: 'Client.SetVolume',
params: {
id: action.id,
volume: {
muted: client.mute,
percent: action.volume,
},
},
};
request(
store,
data,
2019-09-05 15:36:11 +12:00
(response) => {
store.dispatch(snapcastActions.clientLoaded(
{
id: action.id,
volume: response.volume.percent,
},
));
},
(error) => {
store.dispatch(coreActions.handleException(
'Error',
error,
error.message,
));
},
);
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,
},
};
request(
store,
data,
(response) => {
store.dispatch(snapcastActions.clientLoaded(
{
id: action.id,
latency: response.latency,
},
));
},
(error) => {
store.dispatch(coreActions.handleException(
'Error',
error,
error.message,
));
},
);
break;
case 'SNAPCAST_SET_CLIENT_GROUP':
var group = snapcast.groups[action.group_id];
var { clients_ids } = group;
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,
},
};
request(
store,
data,
2019-09-05 15:36:11 +12:00
(response) => {
store.dispatch(snapcastActions.serverLoaded(response.server));
},
(error) => {
store.dispatch(coreActions.handleException(
'Error',
error,
error.message,
));
},
);
break;
case 'SNAPCAST_DELETE_CLIENT':
var data = {
method: 'Server.DeleteClient',
params: {
id: action.id,
},
};
request(
store,
data,
2019-09-05 15:36:11 +12:00
(response) => {
store.dispatch({
type: 'SNAPCAST_CLIENT_REMOVED',
key: action.data.params.id,
});
},
(error) => {
store.dispatch(coreActions.handleException(
'Error',
error,
error.message,
));
},
);
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,
},
};
request(
store,
data,
2019-09-05 15:36:11 +12:00
(response) => {
store.dispatch(snapcastActions.groupLoaded(
{
id: action.id,
stream_id: action.stream_id,
},
));
},
(error) => {
store.dispatch(coreActions.handleException(
'Could not change stream',
error,
error.message,
));
},
);
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,
},
};
request(
store,
data,
2019-09-05 15:36:11 +12:00
(response) => {
store.dispatch(snapcastActions.groupLoaded(
{
id: action.id,
muted: response.mute,
},
));
},
(error) => {
store.dispatch(coreActions.handleException(
'Could not toggle mute',
error,
error.message,
));
},
);
break;
case 'SNAPCAST_SET_GROUP_VOLUME':
var clients_to_update = [];
var group = snapcast.groups[action.id];
var change = action.percent - action.old_percent;
for (const client_id of group.clients_ids) {
// Apply the change proportionately to each client
var client = snapcast.clients[client_id];
const current_volume = client.volume;
const new_volume = current_volume + change;
// Only change if the client is within min/max limits
if ((change > 0 && current_volume < 100) || (change < 0 && current_volume > 0)) {
clients_to_update.push({
id: client.id,
volume: new_volume,
});
}
2018-09-24 08:26:50 +12:00
}
2019-09-05 15:36:11 +12:00
// Loop our required changes, and post each to Snapcast
for (const client_to_update of clients_to_update) {
let volume = client_to_update.volume + ((group.clients_ids.length - clients_to_update.length) * change);
// Make sure we're not creating an impossible percent
if (volume < 0) {
volume = 0;
} else if (volume > 100) {
volume = 100;
}
store.dispatch(snapcastActions.setClientVolume(client_to_update.id, volume));
}
break;
case 'SNAPCAST_EVENT_RECEIVED':
// Drop the prefix
action.method = action.method.replace('snapcast_', '');
switch (action.method) {
case 'Client.OnConnect':
store.dispatch(snapcastActions.clientLoaded(
{
id: action.params.client.id,
name: action.params.client.name,
volume: action.params.client.volume.percent,
mute: action.params.client.volume.muted,
connected: action.params.client.connected,
},
));
break;
case 'Client.OnDisconnect':
store.dispatch(snapcastActions.clientLoaded(
{
id: action.params.client.id,
connected: action.params.client.connected,
},
));
break;
case 'Client.OnVolumeChanged':
store.dispatch(snapcastActions.clientLoaded(
{
id: action.params.id,
mute: action.params.volume.muted,
volume: action.params.volume.percent,
},
));
break;
case 'Client.OnLatencyChanged':
store.dispatch(snapcastActions.clientLoaded(
{
id: action.params.id,
latency: action.params.latency,
},
));
break;
case 'Client.OnNameChanged':
store.dispatch(snapcastActions.clientLoaded(
{
id: action.params.id,
name: action.params.name,
},
));
break;
case 'Group.OnMute':
store.dispatch(snapcastActions.groupLoaded(
{
id: action.params.id,
mute: action.params.mute,
},
));
break;
case 'Server.OnUpdate':
store.dispatch(snapcastActions.serverLoaded(action.params));
break;
}
break;
// This action is irrelevant to us, pass it on to the next middleware
default:
return next(action);
}
};
}());
2018-09-24 08:26:50 +12:00
2019-09-05 15:36:11 +12:00
export default SnapcastMiddleware;