Calculating group volume on render rather than on load, fixes #534

This commit is contained in:
James Barnsley
2020-05-16 19:17:22 +12:00
parent 65b3a3349a
commit afb06bac4a
9 changed files with 85 additions and 97 deletions

View File

@ -9,7 +9,7 @@ import DropdownField from './DropdownField';
import * as coreActions from '../../services/core/actions';
import * as pusherActions from '../../services/pusher/actions';
import * as snapcastActions from '../../services/snapcast/actions';
import { sortItems, indexToArray } from '../../util/arrays';
import { sortItems, indexToArray, applyFilter } from '../../util/arrays';
import { collate } from '../../util/format';
class OutputControl extends React.Component {
@ -23,12 +23,6 @@ class OutputControl extends React.Component {
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
if (!this.props.force_expanded && $(e.target).closest('.output-control').length <= 0) {
this.setExpanded(false);
}
}
componentDidUpdate = ({
force_expanded: prev_force_expanded,
}) => {
@ -53,12 +47,19 @@ class OutputControl extends React.Component {
}
}
handleClick(e) {
if (!this.props.force_expanded && $(e.target).closest('.output-control').length <= 0) {
this.setExpanded(false);
}
}
snapcastGroups() {
const {
snapcast_streams,
snapcastActions,
snapcast_groups,
snapcast_clients: clients,
show_disconnected_clients
} = this.props;
const groups = indexToArray(snapcast_groups);
@ -73,13 +74,18 @@ class OutputControl extends React.Component {
{
groups.map((simpleGroup) => {
const group = collate(simpleGroup, { clients });
if (
!group.clients ||
!group.clients.length ||
!group.clients.filter((client) => client.connected).length
) {
return null;
let { clients: groupClients = [] } = group;
if (!show_disconnected_clients) {
groupClients = applyFilter('connected', true, groupClients);
}
if (!groupClients.length) return null;
const volume = groupClients.reduce(
(acc, client) => acc + (client.volume || 0),
0,
) / groupClients.length;
return (
<div className="output-control__item outputs__item--snapcast" key={group.id}>
<div className="output-control__item__name">
@ -102,7 +108,7 @@ class OutputControl extends React.Component {
/>
<VolumeControl
className="output-control__item__volume"
volume={group.volume}
volume={volume}
mute={group.mute}
onVolumeChange={(percent, previousPercent) => snapcastActions.setGroupVolume(group.id, percent, previousPercent)}
/>

View File

@ -1,19 +1,12 @@
import React from 'react';
import { applyFilter } from '../util/arrays';
import VolumeControl from './Fields/VolumeControl';
import MuteControl from './Fields/MuteControl';
import LatencyControl from './Fields/LatencyControl';
import TextField from './Fields/TextField';
import SelectField from './Fields/SelectField';
const SnapcastClients = ({ actions, group, groups, show_disconnected_clients }) => {
if (!show_disconnected_clients && group.clients) {
var clients = applyFilter('connected', true, group.clients);
} else {
var { clients } = group;
}
const SnapcastClients = ({ actions, group, clients, groups }) => {
if (!clients || clients.length <= 0) {
return <p className="no-results">No connected clients</p>;
}

View File

@ -3,7 +3,7 @@ import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { collate } from '../util/format';
import { sortItems } from '../util/arrays';
import { sortItems, applyFilter } from '../util/arrays';
import { iconFromKeyword } from '../util/helpers';
import VolumeControl from './Fields/VolumeControl';
import MuteControl from './Fields/MuteControl';
@ -39,6 +39,19 @@ const SnapcastGroups = (props) => {
const renderGroup = () => {
if (!group) return null;
let { clients: groupClients = [] } = group;
if (!show_disconnected_clients) {
groupClients = applyFilter('connected', true, groupClients);
}
let volume = 0;
if (groupClients.length) {
volume = groupClients.reduce(
(acc, client) => acc + (client.volume || 0),
0,
) / groupClients.length;
};
return (
<div className="snapcast__group" key={group.id}>
<div className="field text">
@ -48,7 +61,7 @@ const SnapcastGroups = (props) => {
<div className="input">
<TextField
value={group.name}
onChange={value => actions.setGroupName(group.id, value)}
onChange={(value) => actions.setGroupName(group.id, value)}
autosave
/>
</div>
@ -84,17 +97,17 @@ const SnapcastGroups = (props) => {
/>
<VolumeControl
className="snapcast__group__volume-control snapcast__volume-control"
volume={group.volume}
volume={volume}
mute={group.mute}
onVolumeChange={(percent, previousPercent) => actions.setGroupVolume(group.id, percent, previousPercent)}
/>
</div>
</div>
<SnapcastClients
clients={groupClients}
group={group}
groups={groupsArray}
actions={actions}
show_disconnected_clients={show_disconnected_clients}
/>
</div>
);

View File

@ -306,7 +306,6 @@ const SnapcastMiddleware = (function () {
if (raw_group.clients) {
group.clients_ids = 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
@ -326,18 +325,6 @@ const SnapcastMiddleware = (function () {
next(action);
break;
case 'SNAPCAST_CALCULATE_GROUP_VOLUME':
const totalVolume = action.clients.reduce((accumulator, client) =>
accumulator += 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 = [];

View File

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