Averaging group volume for state

This commit is contained in:
James Barnsley
2019-11-08 16:39:25 +13:00
parent 0efa8a2277
commit 6cbb8823e5
11 changed files with 10063 additions and 5476 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -100,7 +100,7 @@
// Release details
// These are automatically injected to built HTML
var build = "1573150704";
var build = "1573154618";
var version = "3.42.2";
// Construct the script tag

View File

@ -56,44 +56,41 @@ class OutputControl extends React.Component {
renderOutputs() {
let has_outputs = false;
const clients = [];
for (var key in this.props.snapcast_clients) {
if (this.props.snapcast_clients.hasOwnProperty(key)) {
const client = this.props.snapcast_clients[key];
if (client.connected || this.props.show_disconnected_clients) {
clients.push(client);
}
const groups = [];
for (var key in this.props.snapcast_groups) {
if (this.props.snapcast_groups.hasOwnProperty(key)) {
groups.push(this.props.snapcast_groups[key]);
}
}
let snapcast_clients = null;
if (clients.length > 0) {
let snapcast_groups = null;
if (groups.length > 0) {
has_outputs = true;
snapcast_clients = (
snapcast_groups = (
<div>
{
clients.map(client => (
<div className="output-control__item outputs__item--snapcast" key={client.id}>
groups.map(group => (
<div className="output-control__item outputs__item--snapcast" key={group.id}>
<div className="output-control__item__name">
{client.name}
{group.name}
</div>
<div className="output-control__item__controls">
<MuteControl
className="output-control__item__mute"
noTooltip
mute={client.mute}
onMuteChange={(mute) => this.props.snapcastActions.setClientMute(client.id, mute)}
mute={group.mute}
onMuteChange={(mute) => this.props.snapcastActions.setGroupMute(group.id, mute)}
/>
<VolumeControl
className="output-control__item__volume"
volume={client.volume}
mute={client.mute}
onVolumeChange={(percent) => this.props.snapcastActions.setClientVolume(client.id, percent)}
volume={group.volume}
mute={group.mute}
onVolumeChange={(percent) => this.props.snapcastActions.setGroupVolume(group.id, percent)}
/>
</div>
</div>
))
}
))
}
</div>
);
}
@ -141,14 +138,14 @@ class OutputControl extends React.Component {
<div className="output-control__item output-control__item--commands commands">
{
commands_items.map((command) => (
<div
key={command.id}
className="commands__item commands__item--interactive"
onClick={(e) => this.props.pusherActions.runCommand(command.id)}
>
<Icon className="commands__item__icon" name={command.icon} />
<span className={`${command.colour}-background commands__item__background`} />
</div>
<div
key={command.id}
className="commands__item commands__item--interactive"
onClick={(e) => this.props.pusherActions.runCommand(command.id)}
>
<Icon className="commands__item__icon" name={command.icon} />
<span className={`${command.colour}-background commands__item__background`} />
</div>
))
}
</div>
@ -167,7 +164,7 @@ class OutputControl extends React.Component {
<div className="output-control__items">
{commands}
{local_streaming}
{snapcast_clients}
{snapcast_groups}
</div>
);
}
@ -205,7 +202,7 @@ const mapStateToProps = (state, ownProps) => ({
pusher_connected: state.pusher.connected,
snapcast_enabled: (state.pusher.config ? state.pusher.config.snapcast_enabled : null),
show_disconnected_clients: (state.ui.snapcast_show_disconnected_clients !== undefined ? state.ui.snapcast_show_disconnected_clients : false),
snapcast_clients: state.snapcast.clients,
snapcast_groups: state.snapcast.groups,
pusher_commands: (state.pusher.commands ? state.pusher.commands : {}),
});

View File

@ -8,7 +8,11 @@ const SelectField = ({ onChange, value, options }) => (
onChange={(e) => onChange(e.target.value)}
value={value}
>
{options.map((option) => <option value={option.value}>{option.label}</option>)}
{options.map((option) => (
<option value={option.value} key={option.key || option.value}>
{option.label}
</option>
))}
</select>
<Icon name="arrow_drop_down" className="select-field__icon" />
</div>

View File

@ -60,8 +60,16 @@ const SnapcastClients = ({ actions, group, groups, show_disconnected_clients })
onChange={(value) => actions.setClientGroup(client.id, value)}
value={group.id}
options={[
...groups.map((group) => ({ value: group.id, label: group.name })),
{ value: group.id, label: 'New group' },
...groups.map((group) => ({
key: `client_${client.id}_group_${group.id}`,
value: group.id,
label: group.name,
})),
{
key: `client_${client.id}_new_group`,
value: group.id,
label: 'New group',
},
]}
/>
</div>
@ -80,7 +88,7 @@ const SnapcastClients = ({ actions, group, groups, show_disconnected_clients })
className="snapcast__volume-control snapcast__client__volume-control"
volume={client.volume}
mute={client.mute}
onVolumeChange={(percent) => actions.setClientVolume(client.id, percent)}
onVolumeChange={(percent) => actions.setClientVolume(client.id, percent, group.id)}
/>
</div>
</div>

View File

@ -39,14 +39,6 @@ const SnapcastGroups = (props) => {
const group = helpers.collate(groups[groupId], { clients });
// Average our clients' volume for an overall group volume
let group_volume = 0;
for (let i = 0; i < group.clients.length; i++) {
const client = group.clients[i];
group_volume += client.volume;
}
group_volume /= group.clients.length;
return (
<div className="snapcast__group" key={group.id}>
<div className="field text">
@ -69,7 +61,11 @@ const SnapcastGroups = (props) => {
onChange={(value) => actions.setGroupStream(group.id, value)}
value={group.stream_id}
options={streamsArray.map((stream) => (
{ value: stream.id, label: `${stream.id} (${stream.status})` }
{
key: `group_${group.id}_stream_${stream.id}`,
value: stream.id,
label: `${stream.id} (${stream.status})`,
}
))}
/>
</div>
@ -86,7 +82,7 @@ const SnapcastGroups = (props) => {
/>
<VolumeControl
className="snapcast__group__volume-control snapcast__volume-control"
volume={group_volume}
volume={group.volume}
mute={group.mute}
onVolumeChange={(percent, previousPercent) => actions.setGroupVolume(group.id, percent, previousPercent)}
/>

View File

@ -869,6 +869,7 @@ export const formatGroup = function (data) {
'id',
'name',
'mute',
'volume',
'stream_id',
'clients_ids',
];

View File

@ -71,11 +71,12 @@ export function setClientMute(id, mute) {
};
}
export function setClientVolume(id, volume) {
export function setClientVolume(id, volume, group_id = null) {
return {
type: 'SNAPCAST_SET_CLIENT_VOLUME',
id,
volume,
group_id,
};
}
@ -135,6 +136,15 @@ export function setGroupVolume(id, percent, old_percent = 0) {
};
}
export function calculateGroupVolume(id, clients) {
return {
type: 'SNAPCAST_CALCULATE_GROUP_VOLUME',
id,
clients,
};
}
/**
* Record loaders
@ -167,7 +177,6 @@ export function groupsLoaded(groups, flush = false) {
return {
type: 'SNAPCAST_GROUPS_LOADED',
groups,
flush,
};
}

View File

@ -297,6 +297,7 @@ const SnapcastMiddleware = (function () {
if (raw_group.clients) {
group.clients_ids = helpers.arrayOf('id', raw_group.clients);
clients_loaded = [...clients_loaded, ...raw_group.clients];
store.dispatch(snapcastActions.calculateGroupVolume(group.id, raw_group.clients));
}
// Create a name (display only) based on it's ID
@ -316,6 +317,17 @@ const SnapcastMiddleware = (function () {
next(action);
break;
case 'SNAPCAST_CALCULATE_GROUP_VOLUME':
const totalVolume = action.clients.reduce((accumulator, client) => {
return accumulator += helpers.formatClient(client).volume;
}, 0);
store.dispatch(snapcastActions.groupLoaded({
id: action.id,
volume: totalVolume / action.clients.length,
}));
break;
case 'SNAPCAST_CLIENTS_LOADED':
var clients_index = { ...snapcast.clients };
var clients_loaded = [];
@ -405,6 +417,15 @@ const SnapcastMiddleware = (function () {
volume: response.volume.percent,
},
));
/*
// A group was referenced, so we should update the group's averaged volume
if (action.group_id) {
const group = snapcast.groups[action.group_id];
const clients = [];
snapcast.groups.filter
store.dispatch(snapcastActions.calculateGroupVolume(group.id, clients));
}
*/
},
(error) => {
store.dispatch(coreActions.handleException(

View File

@ -36,7 +36,10 @@ export default function reducer(snapcast = {}, action) {
}
for (const group of action.groups) {
groups[group.id] = group;
groups[group.id] = {
...(groups[group.id] ? groups[group.id] : {}),
...group,
}
}
return { ...snapcast, groups };